# HG changeset patch
# User danieleb
' . 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 d72257b2ddc2 -r a75ead649730 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:18:21 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 d72257b2ddc2 -r a75ead649730 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:18:21 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
' . 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'] = ' '; + + // 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 .= '" . 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('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('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.') . "
"; + return ($text); +} +/** + * Implementation of hook_help(). + * + * Throughout Drupal, hook_help() is used to display help text at the top of + * pages. Some other parts of Drupal pages get explanatory text from these hooks + * as well. We use it here to provide a description of the module on the + * module administration page. + */ + +function biblio_help($path, $arg) { + switch ($path) { + case 'admin/help#biblio' : + return biblio_help_page(); + case 'admin/modules#description' : + // This description is shown in the listing at admin/modules. + return t('Manages a list of scholarly papers on your site'); + case 'node/add#biblio' : + // This description shows up when users click "create content." + return t('This allows you to add a bibliographic entry to the database'); + } +} + +function biblio_node_info() { + return array( + 'biblio' => array( + 'name' => t('Biblio'), + 'base' => 'biblio', + 'description' => t('Use Biblio for scholarly content, such as journal papers and books.'), + ) + ); +} + +function biblio_node_access($node, $op, $account) { + if (is_string($node)) { + return NODE_ACCESS_IGNORE; + } + + if ($node->type != 'biblio') { // we only care about biblio nodes + return NODE_ACCESS_IGNORE; + } + switch ($op) { + case 'view': + if (((variable_get('biblio_view_only_own', 0)) && $account->uid != $node->uid) || + !user_access('access biblio content')){ + return NODE_ACCESS_DENY; + } + break; + case 'update': + case 'delete': + if (user_access('edit by all biblio authors') && isset($node->biblio_contributors) && is_array($node->biblio_contributors)) { + foreach ($node->biblio_contributors as $key => $author) { + if ((isset($author['drupal_uid']) && $author['drupal_uid'] == $account->uid) || + (isset($account->data['biblio_contributor_id']) && $author['cid'] == $account->data['biblio_contributor_id'])) { + return NODE_ACCESS_ALLOW; + } + } + } + break; + default: + } + return NODE_ACCESS_IGNORE; +} + +function biblio_access($op, $node = '') { + global $user; + + switch ($op) { + case 'admin': + return user_access('administer biblio'); + case 'import': + return user_access('import from file'); + case 'export': + return user_access('show export links'); + case 'edit_author': + if (user_access('administer biblio') || user_access('edit biblio authors')) return NODE_ACCESS_ALLOW; + break; + case 'download': + if (user_access('show download links') || (user_access('show own download links') && ($user->uid == $node->uid))) return NODE_ACCESS_ALLOW; + break; + case 'rss': + return variable_get('biblio_rss', 0); + default: + } + return NODE_ACCESS_IGNORE; +} +/** + * Implementation of hook_permission(). + * + * Since we are limiting the ability to create new nodes to certain users, + * we need to define what those permissions are here. We also define a permission + * to allow users to edit the nodes they created. + */ +function biblio_permission() { + return array( + 'administer biblio' => array( + 'title' => t('Administer Biblio'), + 'description' => t('Allows full control (create, update, delete) of all Biblio nodes'), + ), + 'access biblio content' => array( + 'title' => t('Access Biblio content'), + 'description' => t('Allows the user to view Biblio nodes'), + ), +// 'create biblio' => array( +// 'title' => t('Create Biblio'), +// 'description' => t('Allows the user to create new Biblio nodes'), +// ), +// 'edit all biblio entries' => array( +// 'title' => t('Edit all Biblio entries'), +// 'description' => t('Allows the user to edit ALL biblio entries regardless of who "owns" them, otherwise they are restricted to on'), +// ), + 'edit by all biblio authors' => array( + 'title' => t('Edit by all Biblio authors'), + 'description' => t('Allows any/all of the authors associated with a biblio entry to edit the biblio entry. This requires the Drupal UserID be mapped to a Biblio author ID'), + ), + 'edit biblio authors' => array( + 'title' => t('Edit Biblio authors'), + 'description' => t('Allows the user to edit author information'), + ), + 'import from file' => array( + 'title' => t('Import from file'), + 'description' => t('Allows the user to import bibliographic data from files such as BibTex, RIS, EndNote'), + ), + 'show export links' => array( + 'title' => t('Show export links'), + 'description' => t('Allows users to see links which allow export of bibliographic data for an individual entry or the entire result set'), + ), + 'show download links' => array( + 'title' => t('Show download links'), + 'description' => t('Allows users to see links to any attachements associated with the Biblio entry'), + ), + 'show own download links' => array( + 'title' => t('Show own download links'), + 'description' => t('Allows user to only see download links on entries for which they are the owner.'), + ), + 'show filter tab' => array( + 'title' => t('Show filter tab'), + 'description' => t('This determines if the "Filter" tab on the Biblio list page will be shown to the user'), + ), + 'show sort links' => array( + 'title' => t('Show sort links'), + 'description' => t('This determines if the "Sort" links on the Biblio list page will be shown to the user'), + ), + 'view full text' => array( + 'title' => t('Show full text'), + 'description' => t('This determines if the user will be able to access the "Full Text" of the article if it is available'), + ), + ); +} + +/** + * Implementation of hook_user(). + */ +function biblio_form_user_profile_form_alter(&$form, &$form_state, $form_id) { + if ($form['#user_category'] == 'account') { + $account = $form['#user']; + include_once drupal_get_path('module', 'biblio') . '/includes/biblio.admin.inc'; + $show_form = variable_get('biblio_show_user_profile_form', '1') || + variable_get('biblio_show_crossref_profile_form', '1') || + variable_get('biblio_show_openurl_profile_form', '1'); + + $admin_show_form = ($account->uid == 1 || (user_access('administer users') && user_access('administer biblio'))) ? TRUE : FALSE; + if ($admin_show_form || $show_form) { + $form['biblio_fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Biblio settings'), + '#weight' => 5, + '#collapsible' => TRUE, + '#collapsed' => FALSE, + ); + if ($admin_show_form || variable_get('biblio_show_user_profile_form', '1')) { + $form['biblio_fieldset'] += _biblio_get_user_profile_form($account); + } + else { + $form['biblio_fieldset'] += _biblio_drupal_author_user_map($account); + } + if ($admin_show_form || variable_get('biblio_show_openurl_profile_form', '1')) { + $form['biblio_fieldset'] += _biblio_get_user_openurl_form($account); + } + if ($admin_show_form || variable_get('biblio_show_crossref_profile_form', '1')) { + $form['biblio_fieldset'] += _biblio_get_user_doi_form($account); + } + } + } +} + +function biblio_forms() { + $forms['biblio_admin_author_types_form_new'] = array( + 'callback' => 'biblio_admin_author_types_form', + ); + $forms['biblio_admin_author_types_form_edit'] = array( + 'callback' => 'biblio_admin_author_types_form', + ); + return $forms; + +} +/** + * Implementation of hook_menu(). + * + * Here we define some built in links for the biblio module, links exposed are: + * + * + */ +function biblio_menu() { + global $user; + $items = array(); + $base = variable_get('biblio_base', 'biblio'); + $base_title = check_plain(variable_get('biblio_base_title', 'Biblio')); + $items["$base"] = array( + 'title' => $base_title, + 'page callback' => 'biblio_page', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', + ); + $items["$base/authors"] = array( + 'title' => 'Authors', + 'page callback' => 'biblio_author_page', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', + 'weight' => 1, + ); + $items["$base/keywords"] = array( + 'title' => 'Keywords', + 'page callback' => 'biblio_keyword_page', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', +// 'type' => MENU_LOCAL_TASK, + 'weight' => 2, + ); + $items["$base/import"] = array( + 'title' => 'Import', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_import_form'), + 'file' => '/includes/biblio.import.export.inc', + 'access callback' => 'user_access', + 'access arguments' => array('import from file'), + // 'type' => MENU_LOCAL_TASK, + 'weight' => 10, + ); + $items["$base/user/%"] = array( + 'title' => 'My publications', + 'page callback' => 'biblio_profile_page', + 'page arguments' => array(2), + 'access callback' => '_biblio_profile_access', + 'access arguments' => array(2, 'menu'), + 'parent' => '', + 'file' => '/includes/biblio.pages.inc', + ); + /* + $items["$base/backup"] = array( + 'title' => '', + 'page callback' => 'biblio_backup', + 'access callback' => 'user_access', + 'access arguments' => array('access content'), + 'file' => 'biblio.import.export.inc', + 'type' => MENU_CALLBACK + ); + */ + $items["$base/pot"] = array( + 'title' => '', + 'page callback' => 'biblio_dump_db_data_for_pot', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'type' => MENU_CALLBACK + ); + + $wildcard = 2 + (count(explode("/", $base)) - 1); + + $items["$base/authors/%/edit"] = array( + 'title' => 'Edit author information', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_author_edit_form', $wildcard), + 'access callback' => 'biblio_access', + 'access arguments' => array('edit_author'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK + ); + $items["$base/keywords/%/edit"] = array( + 'title' => '', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_keyword_edit_form', $wildcard), + 'access callback' => 'user_access', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK + ); + $items["$base/keyword/%/delete"] = array( + 'title' => 'Delete', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_keyword_delete_confirm', $wildcard), + 'access callback' => 'user_access', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'weight' => 1, + 'type' => MENU_CALLBACK + ); + $items["$base/view/%"] = array( + 'page callback' => 'biblio_view_node', + 'page arguments' => array($wildcard), + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', + 'type' => MENU_CALLBACK + ); + + $items["user/%user/$base"] = array( + 'title' => 'Publications', + 'page callback' => 'biblio_profile_page', + 'page arguments' => array(1, 'profile', 'no_filters'), + 'access callback' => '_biblio_profile_access', + 'access arguments' => array(1, 'profile'), + 'file' => '/includes/biblio.pages.inc', + 'type' => MENU_LOCAL_TASK + ); + // The next two "LOCAL TASKS" are for the admin/config/content/biblio page + $items['admin/config/content/biblio'] = array( + 'title' => 'Biblio settings', + 'description' => 'Configure default behavior of the Biblio module.', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_settings'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + ); + + $items['admin/config/content/biblio/basic'] = array( + 'title' => 'Preferences', + 'description' => 'Configure default behavior of the Biblio module.', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_settings'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -10 + ); + $items['admin/config/content/biblio/import'] = array( + 'title' => 'Data import', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_import_form'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.import.export.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => 1 + ); + $items['admin/config/content/biblio/export'] = array( + 'title' => 'Export', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_export_form'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.import.export.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => 2 + ); + $items['admin/config/content/biblio/fields'] = array( + 'title' => 'Fields', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_types_edit_form'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -9 + ); + $items['admin/config/content/biblio/fields/common'] = array( + 'title' => 'Common', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_types_edit_form'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10 + ); + $items['admin/config/content/biblio/iomap'] = array( + 'title' => 'Import/Export Mapping', + 'page callback' => 'biblio_admin_io_mapper_page', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -1 + ); + $items['admin/config/content/biblio/iomap/formats'] = array( + 'title' => 'Import/Export Mapping', + 'page callback' => 'biblio_admin_io_mapper_page', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -100 + ); + $formats = module_invoke_all('biblio_mapper_options'); + foreach ($formats as $key => $format) { + $items['admin/config/content/biblio/iomap/edit/' . $key] = array( + 'title' => $format['title'], + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_io_mapper_form', 6), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'tab_parent' => 'admin/config/content/biblio/iomap', + 'type' => MENU_LOCAL_TASK, + 'weight' => -1 + ); + } + $items['admin/config/content/biblio/iomap/%/%/add'] = array( + 'title' => '', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_io_mapper_add_form', 5, 6), + 'access arguments' => array('administer biblio'), + 'tab_parent' => 'admin/config/content/biblio/iomap', + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK, + 'weight' => -1 + ); + $items['admin/config/content/biblio/pubtype'] = array( + 'title' => 'Publication types', + 'page callback' => 'biblio_admin_types_form', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -9 + ); + $items['admin/config/content/biblio/pubtype/list'] = array( + 'title' => 'List', + 'page callback' => 'biblio_admin_types_form', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10 + ); + $items['admin/config/content/biblio/pubtype/delete/%'] = array( + 'title' => '', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_types_delete_form', 6), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK + ); + $items['admin/config/content/biblio/pubtype/new'] = array( + 'title' => 'Add New Type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_types_add_form'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -9 + ); + $items['admin/config/content/biblio/pubtype/reset'] = array( + 'page callback' => 'biblio_admin_types_reset', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK, + ); + $items['admin/config/content/biblio/fields/reset'] = array( + 'title' => 'Reset all types to defaults', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_types_reset_form'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK + ); + $items['admin/config/content/biblio/pubtype/hide'] = array( + 'title' => '', + 'page callback' => 'biblio_admin_types_hide', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK + ); + $items['admin/config/content/biblio/pubtype/show'] = array( + 'title' => '', + 'page callback' => 'biblio_admin_types_show', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK + ); + $items['admin/config/content/biblio/author'] = array( + 'title' => 'Authors', + 'page callback' => 'biblio_author_page', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -7 + ); + $items['admin/config/content/biblio/author/list'] = array( + 'title' => 'List', + 'page callback' => 'biblio_author_page', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -7 + ); + $items['admin/config/content/biblio/author/%/edit'] = array( + 'title' => 'Edit author information', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_author_edit_form', 5), + 'access callback' => 'biblio_access', + 'access arguments' => array('edit_author'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK, + 'weight' => -6 + ); + $items['admin/config/content/biblio/author/orphans'] = array( + 'title' => 'Orphaned Authors', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_orphans_form'), + 'access arguments' => array('administer biblio'), + 'description' => 'Delete orphaned biblio authors.', + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -6 + ); + $items['admin/config/content/biblio/author/type'] = array( + 'title' => 'Author Types', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_author_types_form', 7, 6), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -5 + ); + + $items['admin/config/content/biblio/author/type/new'] = array( + 'title' => 'Add New Author Type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_author_types_form_new', 'new'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -9 + ); + $items['admin/config/content/biblio/author/type/%/edit'] = array( + 'title' => 'Edit Author Type', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_author_types_form_edit', 'edit', 6), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK, + 'weight' => -9 + ); + $items['admin/config/content/biblio/author/type/%/delete'] = array( + 'title' => 'Delete', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_author_type_delete_confirm', 6), + 'access callback' => 'user_access', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'weight' => 1, + 'type' => MENU_CALLBACK + ); + $items['admin/config/content/biblio/keywords'] = array( + 'title' => 'Keywords', + 'page callback' => 'biblio_keyword_page', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -7 + ); + $items['admin/config/content/biblio/keywords/list'] = array( + 'title' => 'List', + 'page callback' => 'biblio_keyword_page', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -7 + ); + $items['admin/config/content/biblio/keywords/%/edit'] = array( + 'title' => 'Edit keyword information', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_keyword_edit_form', 5), + 'access callback' => 'user_access', + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_CALLBACK, + 'weight' => -6 + ); + $items['admin/config/content/biblio/keywords/orphans'] = array( + 'title' => 'Orphaned Keywords', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_keyword_orphans_form'), + 'access arguments' => array('administer biblio'), + 'description' => 'Delete orphaned biblio keywords.', + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => -6 + ); + /* $items['admin/config/content/biblio/authors/reset'] = array( + 'title' => t('Reset all Author types to defaults'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_admin_author_type_reset_form'), + 'access arguments' => array('administer biblio'), + 'file' => '/includes/biblio.admin.inc', + 'type' => MENU_LOCAL_TASK + ); + */ + $items['biblio/autocomplete'] = array( + 'title' => 'Autocomplete ', + 'page callback' => 'biblio_autocomplete', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'type' => MENU_CALLBACK + ); +/* $items["$base/list"] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10 + ); + $items["$base/filter"] = array( + 'title' => 'Filter', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('biblio_form_filter'), + 'access callback' => 'user_access', + 'access arguments' => array('show filter tab'), + 'type' => MENU_LOCAL_TASK, + 'file' => '/includes/biblio.pages.inc', + 'weight' => -9 + ); +*/ + $items["$base/filter/clear"] = array( + 'title' => '', + 'page callback' => 'biblio_filter_clear', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'type' => MENU_CALLBACK + ); + $items["$base/help"] = array( + 'title' => 'Help', + 'page callback' => 'biblio_help_page', + 'access callback' => 'user_access', + 'access arguments' => array('access biblio content'), + 'type' => MENU_CALLBACK + ); + $items["$base/export"] = array( + 'title' => '', + 'page callback' => 'biblio_export', + 'access callback' => 'user_access', + 'access arguments' => array('show export links'), + 'file' => '/includes/biblio.import.export.inc', + 'type' => MENU_CALLBACK + ); + $items["$base/citekey"] = array( + 'title' => '', + 'page callback' => 'biblio_citekey_view', + 'access arguments' => array('access biblio content'), + 'file' => '/includes/biblio.pages.inc', + 'type' => MENU_CALLBACK + ); + $items["$base/recent/rss.xml"] = array( + 'title' => 'RSS feed', + 'page callback' => 'biblio_recent_feed', + 'access callback' => 'biblio_access', + 'access arguments' => array('rss'), + 'type' => MENU_CALLBACK + ); + return $items; +} + +function biblio_filter_clear() { + $options = array(); + $_SESSION['biblio_filter'] = array(); + $base = variable_get('biblio_base', 'biblio'); + if (isset($_GET['sort'])) { + $options['sort'] = $_GET['sort']; + } + if (isset($_GET['order'])) { + $options['order'] = $_GET['order']; + } + drupal_goto($base, $options); +} + +function biblio_remove_brace($title_string) { + //$title_string = utf8_encode($title_string); + $matchpattern = '/\{\$(?:(?!\$\}).)*\$\}|(\{[^}]*\})/'; + $output = preg_replace_callback($matchpattern, 'biblio_remove_brace_callback', $title_string); + return $output; +} + +function biblio_remove_brace_callback($match) { + if (isset($match[1])) { + $braceless = str_replace('{', '', $match[1]); + $braceless = str_replace('}', '', $braceless); + return $braceless; + } + return $match[0]; +} + +function biblio_node_revision_delete($node) { + if ($node->type == 'biblio') { + db_delete('biblio') + ->condition('vid', $node->vid) + ->execute(); + + db_delete('biblio_contributor') + ->condition(db_and()->condition('nid', $node->nid)->condition('vid', $node->vid)) + ->execute(); + + db_delete('biblio_keyword') + ->condition(db_and()->condition('nid', $node->nid)->condition('vid', $node->vid)) + ->execute(); + } +} + +function biblio_node_insert($node) { + if ($node->type == 'biblio') { + if (variable_get('biblio_index', 0)) { + _node_index_node($node); + search_update_totals(); + } + } +} + +function biblio_node_update($node) { + if ($node->type == 'biblio') { + if (variable_get('biblio_index', 0)) { + // _node_index_node performs a node_load without resetting the node_load cache, + // so it would index the old version. We reset the cache here. + // Don't assign node_load to $node because node_load resets e.g. the menus mlid etc. + $mynode = node_load($node->nid, NULL, TRUE); + _node_index_node($mynode); + search_update_totals(); + } + } +} + +function biblio_node_view($node, $view_mode) { + if ($node->type == 'biblio') { + switch ($view_mode) { + case 'full': + if (variable_get('biblio_hide_bibtex_braces', 0) && !empty($a4)) { + drupal_set_title(filter_xss($node->title, biblio_get_allowed_tags())); + } + //fall through + case 'teaser': + $show_link = variable_get('biblio_lookup_links', array('google' => TRUE)); + if (!empty($show_link['google'])) { + $node->content['links']['biblio_google_scholar'] = array( + '#links' => array(theme('google_scholar_link', array('node' => $node))), + '#attributes' => array('class' => array('links', 'inline')), + ); + } + } + } +} + +function biblio_query_node_access_alter(QueryAlterableInterface $query) { + global $user; + if (user_access('access biblio content', $user)) return; + $tables = $query->getTables(); + foreach ($tables as $alias => $table_info) { + if (!($table_info instanceof SelectQueryInterface)) { + if ( $table_info['table'] == 'node') { + $query->condition($alias .'.type', 'biblio', '<>'); + break; + } + } + } + +} + +function biblio_user_presave(&$edit, $account, $catagory) { + $keys = array_keys($edit); + foreach ($keys as $key) { + if (strpos($key, 'biblio_') !== FALSE && isset($edit[$key])) { + if (isset($account->data['biblio_id_change_count']) && $account->data['biblio_id_change_count'] > 2 + && $key == 'biblio_contributor_id' && $edit[$key] != 0 ) { + $edit[$key] = 0; + } + $edit['data'][$key] = $edit[$key]; + if ($key == 'biblio_contributor_id' ) { + if ($edit[$key] != 0 && $edit[$key] != $account->data[$key]) { + $edit['biblio_id_change_count']++; + } + db_update('biblio_contributor_data')->condition('drupal_uid', $account->uid)->fields(array('drupal_uid' => 0))->execute(); + db_update('biblio_contributor_data')->condition('cid', $edit['biblio_contributor_id'])->fields(array('drupal_uid' => $account->uid))->execute(); + } + } + } +} + +/** + * Implementation of hook_form(). + * + * Create the form for collecting the information + * specific to this node type. This hook requires us to return some HTML + * that will be later placed inside the form. + */ +function biblio_form($node, &$form_state) { + global $user; + $path = drupal_get_path('module', 'biblio'); + if (variable_get('biblio_button_hide', 1) == 1) { + drupal_add_js($path . '/misc/biblio.nodeformbuttonhide.js', 'file'); + } + $fields = array(); + $form['biblio_tabs'] = $tabs = array(); + + $tid = !empty($form_state['biblio_type']) ? $form_state['biblio_type'] : + ( isset($node->biblio_type) ? $node->biblio_type : 0); + + $step_two = !empty($tid); + + /* publication type */ + $param['options'] = array("enctype" => "multipart/form-data"); + $result = db_query('SELECT t.* FROM {biblio_types} as t WHERE tid > -2 AND visible = 1'); + foreach ($result as $option) { + $results[$option->tid] = $option->name; + } + asort($results); + $options[0] = t('Select Type...'); + $options += $results; + $form['biblio_type'] = array( + '#type' => 'select', + '#title' => t('Publication Type'), + '#default_value' => $tid, + '#options' => $options, + '#description' => NULL, + '#weight' => 2, + '#attributes' => array('onchange' => 'document.getElementById(\'edit-biblio-next\').click()'), + '#executes_submit_callback' => TRUE, + '#limit_validation_errors' => array(), + '#multiple' => FALSE, + '#required' => TRUE + ); + + $form['biblio_next'] = array( + '#type' => 'submit', + '#value' => $step_two ? t('Change Publication Type') : t('Next'), + '#limit_validation_errors' => array(), + '#weight' => -10, + '#submit' => array(), + ); + if (isset($_COOKIE['has_js']) && !$_COOKIE['has_js']) { + unset($form['biblio_next']['#attributes']); + } + + if ($step_two) { + $form['title'] = array( + '#type' => 'textfield', + '#title' => t('Title'), + '#required' => TRUE, + '#default_value' => trim((isset($form_state['values']['title'])?$form_state['values']['title']: $node->title)), + '#maxlength' => 255, + '#size' => 120, + '#weight' => 1 + ); + // Build the field array used to make the form + $result = db_query("SELECT * FROM {biblio_fields} b + INNER JOIN {biblio_field_type} bt ON b.fid = bt.fid + INNER JOIN {biblio_field_type_data} btd ON btd.ftdid=bt.ftdid + WHERE bt.tid=:tid ORDER BY bt.weight ASC", array(':tid' => $tid), array('fetch' => PDO::FETCH_ASSOC)); + + foreach ($result as $row) { + $fields[$row['name']] = $row; + } + _biblio_localize_fields($fields); + + $tabs = array( + '#type' => 'vertical_tabs', + '#weight' => 10, + ); + $tabs += biblio_node_form_vtabs(); + + $tabs['biblio_authors'] = array( + '#type' => 'fieldset', + '#group' => 'biblio_tabs', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#title' => 'Authors', + '#description' => t('Enter a single name per line using a format such as "Smith, John K" or "John K Smith" or "J.K. Smith"'), + ); + + $tabs['biblio_authors'] += biblio_contributor_widget($node, $form_state); + + $form_state['biblio_fields'] = $fields; + + foreach ($fields as $key => $fld) { + $options = ''; + if ($key == 'biblio_keywords' ) { + $sep = check_plain(variable_get('biblio_keyword_sep', ',')); + // is the kewords are in array form, then implode them into a string. + if (isset($form_state['values']['biblio_keywords']) && + is_array($form_state['values']['biblio_keywords'])) { + require_once(drupal_get_path('module', 'biblio') . '/includes/biblio.keywords.inc'); + $form_state['values']['biblio_keywords'] = biblio_implode_keywords($form_state['values']['biblio_keywords']); + } + if (!empty($node->$key) && is_array($node->$key)) { + require_once(drupal_get_path('module', 'biblio') . '/includes/biblio.keywords.inc'); + $node->$key = biblio_implode_keywords($node->$key); + } + if (empty($fld['hint'])) { + $fld['hint'] = t('Separate keywords using the " @sep " character', array('@sep' => $sep)); + } + } + + $element = array( + '#default_value' => (isset($form_state['values'][$key]) ? $form_state['values'][$key] : (isset($node->$key)?$node->$key:'')), + '#type' => $fld['type'], + '#title' => check_plain($fld['title']), + '#size' => $fld['size'], + '#rows' => 10, +// '#required' => $fld['required'], + '#maxlength' => $fld['maxsize'], + '#weight' => $fld['weight'] / 10, + '#autocomplete_path' => ($fld['autocomplete']) ? 'biblio/autocomplete/' . $fld['name'] : '', + '#description' => check_plain($fld['hint']), + '#format' => isset($node->biblio_formats[$key]) ? $node->biblio_formats[$key] : filter_default_format(), + ); + + if ($key == 'biblio_refereed' ) { + $element['#options'] = array( + '' => t('None'), + 'Refereed' => t('Refereed'), + 'Non-Refereed' => t('Non-Refereed'), + 'Does Not Apply' => t('Does Not Apply'), + 'Unknown' => t('Unknown'), + ); + $element['#description'] = t('If you are not sure, set this to Unknown or Does Not Apply'); + } + + if ( $fld['common'] || $fld['visible'] ) { + $tabs[$fld['vtab']][$key] = $element; + } + + } + } + foreach (element_children($tabs) as $key) { + $tab_children = element_children($tabs[$key]); + if (empty($tab_children) && $key != 'biblio_full_text') { + unset($tabs[$key]); + } + } + // $form['format'] = filter_form($node->format, 20); + //$biblio_form['#tree'] = TRUE; + $form['#validate']= array('biblio_node_form_validate'); + $form['#cache'] = TRUE; + $form['biblio_tabs'] += $tabs; + + return $form; +} + +function biblio_node_form_vtab_info() { + return array( + array('tab_id' => 1, 'weight' => 10, 'title' => 'Abstract', 'description' => ''), + array('tab_id' => 'biblio_full_text', 'weight' => 11, 'title' => 'Full text', 'description' => ''), + array('tab_id' => 2, 'weight' => 12, 'title' => 'Publication', 'description' => ''), + array('tab_id' => 3, 'weight' => 13, 'title' => 'Publisher', 'description' => ''), + array('tab_id' => 4, 'weight' => 14, 'title' => 'Identifiers', 'description' => ''), + array('tab_id' => 5, 'weight' => 15, 'title' => 'Locators', 'description' => 'URL\'s etc'), + array('tab_id' => 6, 'weight' => 16, 'title' => 'Keywords', 'description' => ''), + array('tab_id' => 7, 'weight' => 17, 'title' => 'Notes', 'description' => ''), + array('tab_id' => 8, 'weight' => 18, 'title' => 'Alternate Titles', 'description' => ''), + array('tab_id' => 9, 'weight' => 19, 'title' => 'Other', 'description' => ''), + ); +} + +function biblio_node_form_vtabs() { + $vtabs = biblio_node_form_vtab_info(); + + foreach ($vtabs as $tab) { + $form[$tab['tab_id']] = array( + '#type' => 'fieldset', + '#group' => 'biblio_tabs', + '#collapsible' => TRUE, + '#collapsed' => FALSE, + '#title' => t($tab['title']), + '#description' => '', + '#weight' => $tab['weight'] + ); + } + return $form; +} +function biblio_contributor_widget($node, &$form_state) { + $init_count = variable_get('biblio_init_auth_count', 4); + $contributor_count = 0; + if (isset($form_state['values']['biblio_contributors'])) { + $contributors = $form_state['values']['biblio_contributors']; + } + elseif (isset($node->biblio_contributors)) { + $contributors = $node->biblio_contributors; + } + else { + $contributors = array(); + } + + $ctypes = db_query('SELECT * FROM {biblio_contributor_type_data}'); + + foreach ($ctypes as $ctype ) { + $options['roles'][$ctype->auth_type] = $ctype->title; + } + $options['categories'] = array( + 1 => t('Primary'), + 2 => t('Secondary'), + 3 => t('Tertiary'), + 4 => t('Subsidiary'), + 5 => t('Corporate/Institutional') + ); + + // Container for just the contributors. + $wrapper = array(); + $wrapper['biblio_contributors'] = array( + '#tree' => TRUE, + '#theme' => 'biblio_contributors', + '#prefix' => '<bib>citekey</bib> or [bib]citekey[/bib]
. This will be replaced with a running number (the publication reference) and the publication referenced by the citekey within the <bib> tags will be printed at the bottom of the page (the reference).');
+ }
+}
+
+function _biblio_filter_inline_reference_tips($filter, $format, $long = FALSE) {
+ return t('This creates an in line reference to another publication.');
+}
+
+function _biblio_filter_reference_prepare($text, $filter, $format, $langcode, $cache, $cache_id) {
+ return $text;
+}
+
+function _biblio_filter_inline_reference_prepare($text, $filter, $format, $langcode, $cache, $cache_id) {
+ return $text;
+}
+
+function _biblio_filter_reference_process($text, $filter, $format, $langcode, $cache, $cache_id) {
+ $pattern = array('|\[bib](.*?)\[/bib]|s', '|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 .= '[ ' . l(t('Add New Type'), 'admin/config/content/biblio/author/type/new') . ' ]'; + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + $output .= '
[ ' . l(t('Add New Type'), 'admin/config/content/biblio/author/type/new') . ' ]'; + // $output .= ' [ ' . l(t('Reset all types to defaults'), 'admin/config/content/biblio/authors/reset') . ' ]'; + + return $output; +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_author_types_form_submit($form, &$form_state) { + + if ($form_state['triggering_element']['#value'] == t('Save') || $form_state['triggering_element']['#value'] == t('Create New Type')) { + $record->title = $form_state['values']['title']; + $record->hint = $form_state['values']['hint']; + switch ($form['#id']) { + case 'biblio-admin-author-types-form-new': + $record->title = $form_state['values']['title']; + $record->hint = $form_state['values']['hint']; + drupal_write_record('biblio_contributor_type_data', $record); + break; + case 'biblio-admin-author-types-form-edit': + $record->auth_type = $form_state['values']['auth_type']; + drupal_write_record('biblio_contributor_type_data', $record, 'auth_type'); + break; + } + } + $form_state['redirect'] = 'admin/config/content/biblio/author/type'; + +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + * @param unknown_type $type_id + */ +function biblio_admin_author_type_delete_confirm($form, &$form_state, $type_id) { + $base = variable_get('biblio_base', 'biblio'); + $type_data = db_query('SELECT * FROM {biblio_contributor_type_data} bctd WHERE bctd.auth_type = :tid ', array(':tid' => $type_id))->fetchObject(); + $form['auth_type'] = array( + '#type' => 'value', + '#value' => $type_data->auth_type, + ); + + return confirm_form($form, + t('Are you sure you want to delete the author type: %title ?', array('%title' => $type_data->title)), + isset($_GET['destination']) ? $_GET['destination'] : 'admin/config/content/biblio/author/type', + t('This action cannot be undone.'), + t('Delete'), + t('Cancel') + ); + +} +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_author_type_delete_confirm_submit($form, &$form_state) { + + db_delete('biblio_contributor_type_data') + ->condition('auth_type', $form_state['values']['auth_type']) + ->execute(); + + db_delete('biblio_contributor_type') + ->condition('auth_type', $form_state['values']['auth_type']) + ->execute(); + + $form_state['redirect'] = 'admin/config/content/biblio/author/type'; +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + * @param unknown_type $author_id + * @return void|multitype:string NULL + */ +function biblio_admin_author_edit_form($form, &$form_state, $author_id) { + module_load_include('inc', 'biblio', 'includes/biblio.contributors'); + $merge_options = $linked = array(); + if (!isset($form_state['biblio_add_merge_author'])) { + $form_state['biblio_add_merge_author'] = array(); + } + $base = variable_get('biblio_base', 'biblio'); + + $author = db_query('SELECT * FROM {biblio_contributor_data} b WHERE b.cid = :aid ', array(':aid' => $author_id))->fetchObject(); + if (!$author) { + drupal_not_found(); + return; + } + $base = variable_get('biblio_base', 'biblio'); + $menu = menu_get_active_title(); + $path = (strpos($_GET['q'], 'config'))? 'admin/config/content/biblio/author/' : $base . '/authors/'; + + // $form['#tree'] = TRUE; + $form['cid'] = array( + '#type' => 'value', + '#value' => $author_id, + ); + $users = db_query('SELECT uid,name FROM {users} WHERE uid>0 ORDER BY name'); + $options[0] = t('(None)'); + foreach ($users as $user) { + $options[$user->uid] = $user->name; + } + $form['drupal_uid'] = array( + '#type' => 'select', + '#title' => t('Drupal User ID'), + '#options' => $options, + '#default_value' => $author->drupal_uid, + '#weight' => 12, + '#required' => FALSE, + '#description' => t('If this author has a an account (Drupal User ID) on this web site, you may select it here. This will help to link the authors publications with other content.') + ); + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Complete Name'), + '#default_value' => $author->name, + '#size' => 100, + '#weight' => 1, + '#required' => TRUE, + '#disabled' => TRUE, + '#maxlength' => 255, + '#description' => t('The value in this box will be constructed from the individual name parts fields above.') + ); + $form_state['current_name'] = $author->name; + + $form['literal'] = array( + '#type' => 'checkbox', + '#title' => t('Do not reformat'), + '#default_value' => $author->literal, + '#weight' => 1.5, + '#required' => FALSE, + '#description' => t('Selecting this will prevent the styles from trying to reformat the contributor name. The text in the "Complete Name" field will be used as is.') + ); + $form['prefix'] = array( + '#type' => 'textfield', + '#title' => t('Prefix'), + '#default_value' => $author->prefix, + '#size' => 20, + '#weight' => 2, + '#required' => FALSE, + '#maxlength' => 128 + ); + $form['firstname'] = array( + '#type' => 'textfield', + '#title' => t('First Name'), + '#default_value' => $author->firstname, + '#size' => 20, + '#weight' => 3, + '#required' => FALSE, + '#maxlength' => 128 + ); + $form['initials'] = array( + '#type' => 'textfield', + '#title' => t('Initials'), + '#default_value' => $author->initials, + '#size' => 20, + '#weight' => 4, + '#required' => FALSE, + '#maxlength' => 10 + ); + $form['lastname'] = array( + '#type' => 'textfield', + '#title' => t('Last Name'), + '#default_value' => $author->lastname, + '#size' => 20, + '#weight' => 5, + '#required' => FALSE, + '#maxlength' => 255 + ); + $form['suffix'] = array( + '#type' => 'textfield', + '#title' => t('Suffix'), + '#default_value' => $author->suffix, + '#size' => 20, + '#weight' => 6, + '#required' => FALSE, + '#maxlength' => 128 + ); + $form['affiliation'] = array( + '#type' => 'textfield', + '#title' => t('Affiliation'), + '#default_value' => $author->affiliation, + '#size' => 100, + '#weight' => 7, + '#required' => FALSE, + '#maxlength' => 256, + '#description' => t('University, Company or Organization that the author is affiliated with.') + ); + + $query = db_select('biblio_contributor_data', 'bcd'); + $authors = $query->fields('bcd') + ->condition('cid', $author_id, '<>') + ->orderBy('lastname') + ->execute(); + + $query = db_select('biblio_contributor', 'bc'); + $merged_authors = $query->fields('bc') + ->condition('merge_cid', 0, '>') + ->execute(); + foreach ($merged_authors as $auth) { + $merged[$auth->merge_cid] = $auth->cid; + } + + $linked = biblio_get_linked_contributors($author->cid); + + $radio_options = array('link' => '', 'merge' => ''); + $candidate = FALSE; + $candidates = array(); + + $this_soundx = soundex($author->lastname); + + foreach ($authors as $other_author) { + $merge_def = $link_def = 0; + $link_disable = $merge_disable = $retain_disable = FALSE; + + if ((soundex($other_author->lastname) == $this_soundx) || + (isset($merged[$other_author->cid]) && $merged[$other_author->cid] == $author->cid) || + in_array($other_author->cid, $form_state['biblio_add_merge_author'])) { + $candidate = TRUE; + $merge_def = ($other_author->alt_form && $other_author->aka) ? $author->cid : FALSE; + $retain_def = $other_author->alt_form ? $author->cid : FALSE; + $retain_disable = $other_author->alt_form ? TRUE : FALSE; + } + + if (in_array($other_author->cid, $linked)) { + $candidate = TRUE; + $link_def = $author->cid; + $retain_def = 0; + } + + if ($candidate) { + $candidate = FALSE; + $form_state['biblio_add_merge_author'][$other_author->cid] = $other_author->cid; + + $candidates[$other_author->cid]['name'] = array( + '#markup' => l($other_author->lastname . ($other_author->firstname ? ', ' . $other_author->firstname : ($other_author->initials?', ' . $other_author->initials:'')), $path . $other_author->cid . '/edit/'), + '#markup' => l($other_author->name , $path . $other_author->cid . '/edit/'), + ); + $candidates[$other_author->cid]['link'] = array( + '#type' => 'checkbox', + '#return_value' => $author->cid, + '#default_value' => $link_def, + '#disabled' => $link_disable, + '#parents' => array('candidates', $other_author->cid, 'link'), + '#states' => array( + 'disabled' => array( + ':input[name="candidates[' . $other_author->cid . '][merge]"]' => array('checked' => true), + ), + ), + ); + $candidates[$other_author->cid]['merge'] = array( + '#type' => 'checkbox', + '#return_value' => $author->cid, + '#default_value' => $merge_def, + '#disabled' => $merge_disable, + '#parents' => array('candidates', $other_author->cid, 'merge'), + '#states' => array( + 'disabled' => array( + ':input[name="candidates[' . $other_author->cid . '][link]"]' => array('checked' => true), + ), + ), + ); + $candidates[$other_author->cid]['retain'] = array( + '#type' => 'checkbox', + '#return_value' => $author->cid, + '#default_value' => $retain_def, + '#disabled' => $retain_disable, + '#parents' => array('candidates', $other_author->cid, 'retain'), + '#states' => array( + 'enabled' => array( + ':input[name="candidates[' . $other_author->cid . '][merge]"]' => array('checked' => true), + ), + 'unchecked' => array( + ':input[name="candidates[' . $other_author->cid . '][merge]"]' => array('unchecked' => true), + ), + ), + ); + } + } + + $form['merge'] = array( + '#type' => 'fieldset', + '#theme' => 'biblio_admin_author_edit_merge_table', + '#title' => t('Author Link / Merge'), + '#description' => t('Select other author names which will be linked or merged. Merging removes all the selected authors, then replaces any references to these authors with the author being edited above. You should only do this if you are sure the other authors represent the same author as the one being edited. IF you do not select "Retain as alternate form" then THIS CANNOT BE UNDONE!'), + '#weight' => 5, + '#collapsible' => TRUE, + '#collapsed' => !count($candidates), + '#header' => array(t('Author name'), t('Link'), t('Merge'), t('Retain as "alternate form"')), + 'candidates' => $candidates, + '#prefix' => '
', + + ); + $form['merge']['more_authors_search'] = array( + '#type' => 'textfield', + '#title' => t('Other authors which could be linked to this author'), + '#autocomplete_path' => 'biblio/autocomplete/contributor', + '#weight' => 12, + '#required' => FALSE, + ); + $form['merge']['more_authors_add'] = array( + '#type' => 'submit', + '#value' => t('Add author'), + '#weight' => 15, + '#submit' => array('biblio_admin_author_edit_add_candidate'), + '#ajax' => array( + 'callback' => 'biblio_admin_author_edit_add_candidate_callback', + 'wrapper' => 'biblio-author-edit-merge-table', + ), + + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save') + ); + $form['cancel'] = array( + '#type' => 'submit', + '#value' => t('Cancel') + ); + + return $form; +} + +function biblio_admin_author_edit_add_candidate($form, &$form_state) { + module_load_include('inc', 'biblio', 'includes/biblio.contributors'); + if (!empty($form_state['values']['more_authors_search'])) { + if ($cid = biblio_get_cid_by_name($form_state['values']['more_authors_search'])) { + if ($cid == $form_state['values']['cid']) { // we don't want to merge with ourselves :-( + drupal_set_message(t('You cannot merge an author with itself'), 'error'); + } + elseif (in_array($cid, $form_state['biblio_add_merge_author'])) { + drupal_set_message(t('Author already exists in the merge list'), 'warning'); + } + else { + $form_state['biblio_add_merge_author'][$cid] = $cid; + } + } + else { + drupal_set_message(t('The Author was not found in the database. You must select an Author from the "auto-complete" list of the Keyword search box.'), 'error'); + } + } + else { + drupal_set_message(t('Cannot add an empty value'), 'error'); + } + + $form_state['rebuild'] = TRUE; + +} + +function biblio_admin_author_edit_add_candidate_callback($form, $form_state) { + return $form['merge']; +} + +/** + * @param array $form + * @param array $form_state + */ +function biblio_admin_author_edit_form_merge_validate($form, &$form_state) { +} + +/** + * @param array $form + * @param array $form_state + */ +function biblio_admin_author_edit_form_merge_link($form_state) { + $op = $form_state['triggering_element']['#value']; + $merge_authors = array(); + $cid = $form_state['values']['cid']; + + foreach ($form_state['values']['candidates'] as $ccid => $options) { + + if ($options['link']) { + db_update('biblio_contributor_data') + ->fields(array( + 'aka' => $options['link'], + 'alt_form' => 0, + )) + ->condition('cid', $ccid) + ->execute(); + } + else { + db_update('biblio_contributor_data') + ->fields(array( + 'aka' => 0, + 'alt_form' => 0, + )) + ->condition(db_or()->condition('cid', $cid)->condition('cid', $ccid)) + ->execute(); + } + + if ($options['merge']) { + db_update('biblio_contributor') + ->fields(array( + 'cid' => $cid, + 'merge_cid' => $ccid)) + ->condition('cid', $ccid) + ->execute(); + } + else { + db_update('biblio_contributor') + ->fields(array( + 'cid' => $ccid, + 'merge_cid' => 0)) + ->condition('merge_cid', $ccid) + ->execute(); + } + + if ($options['merge'] && $options['retain']) { + db_update('biblio_contributor_data') + ->fields(array( + 'alt_form' => $options['retain'] ? $options['retain'] : 0, + 'aka' => $options['retain'] ? $cid : 0)) + ->condition('cid', $ccid) + ->execute(); + } + elseif ($options['merge'] && !$options['retain']) { + db_delete('biblio_contributor_data') + ->condition('cid', $ccid) + ->execute(); + } + } +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_author_edit_form_link_validate($form, &$form_state) { + +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_author_edit_form_link_submit($form, &$form_state) { + module_load_include('inc', 'biblio', 'includes/biblio.contributors'); + $linked_authors = array(); + $link_authors = ''; + + if (isset($form_state['values']['linked_authors']) ) { + $linked_authors = $form_state['values']['linked_authors']; + } + + if (isset($form_state['values']['link_authors']) ) { + $link_authors = $form_state['values']['link_authors']; + } + + foreach ($linked_authors as $key => $value) { + if ($value == 0) { + db_update('biblio_contributor_data') + ->fields(array('aka' => $value)) + ->condition('cid', $key) + ->execute(); + } + } + + if (!empty($link_authors)) { + if ( ($cid = biblio_get_cid_by_name($link_authors))) { + db_update('biblio_contributor_data') + ->fields(array('aka' => $form_state['values']['cid'])) + ->condition('cid', $cid) + ->execute(); + } + } + +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_author_edit_form_validate($form, &$form_state) { + foreach ($form_state['values'] as $key => $value) { + if (is_string($value)) $form_state['values'][$key] = trim($value); + } +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_author_edit_form_submit($form, &$form_state) { + $op = $form_state['values']['op']; + switch ($op) { + case t('Save'): + if ($form_state['values']['drupal_uid'] == 0 ) { + $uid = $form['drupal_uid']['#default_value']; + $cid = 0; + } + else { + $uid = $form_state['values']['drupal_uid']; + $cid = $form_state['values']['cid'] ; + } + if ($uid) { + db_update('biblio_contributor_data') + ->fields(array('drupal_uid' => 0)) + ->condition('drupal_uid', $uid) + ->execute(); + $result = db_query('SELECT data FROM {users} WHERE uid = :uid', array(':uid' => $uid))->fetchField(); + $data = unserialize($result); + $data['biblio_contributor_id'] = $cid; + $v = serialize($data); + db_update('users') + ->fields(array('data' => $v)) + ->condition('uid', $uid) + ->execute(); + } + + $form_state['values']['name'] = + (!empty($form_state['values']['prefix']) ? $form_state['values']['prefix'] . ' ' :'') . + (!empty($form_state['values']['firstname']) ? $form_state['values']['firstname'] . ' ' :'') . + (!empty($form_state['values']['initials']) ? $form_state['values']['initials'] . ' ' :'') . + (!empty($form_state['values']['lastname']) ? $form_state['values']['lastname'] . ' ' :'') . + (!empty($form_state['values']['suffix']) ? $form_state['values']['suffix'] :'') ; + $form_state['values']['name'] = trim($form_state['values']['name']); + $form_state['values']['md5'] = md5($form_state['values']['name']); + + drupal_write_record('biblio_contributor_data', $form_state['values'], 'cid'); + + if (isset($form_state['values']['candidates']) && !empty($form_state['values']['candidates'])) { + biblio_admin_author_edit_form_merge_link($form_state); + } + break; + case t('Cancel'): + break; + } +} + + +/** + * + * @param $form + * @param $form_state + * @return array + */ +function biblio_admin_orphans_form($form, &$form_state) { + module_load_include('inc', 'biblio', 'includes/biblio.contributors'); + $orphans = $options = $names = array(); + + $base = variable_get('biblio_base', 'biblio'); + + $orphans = biblio_get_orphan_authors(); + + foreach ($orphans as $author) { + $options[$author->cid] = array( + 'author' => array( + 'data' => array( + '#type' => 'link', + '#title' => $author->name, + '#href' => $base . '/authors/' . $author->cid . '/edit', + ), + ), + 'affiliation' => check_plain($author->affiliation), + ); + $names[$author->cid] = $author->name; + } + $form['names'] = array('#type' => 'hidden', '#value' => $names); + + $header = array( + 'author' => t('Author name'), + 'affiliation' => t('Author affiliation') + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Delete Selected'), + '#disabled' => (!count($options)), + '#submit' => array('biblio_admin_orphans_form_submit'), + ); + $form['delete_all'] = array( + '#type' => 'submit', + '#value' => t('Delete ALL'), + '#disabled' => (!count($options)), + '#submit' => array('biblio_admin_orphans_form_submit'), + ); + $form['authors'] = array( + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options, + '#empty' => t('No orphaned authors.'), + ); + + return $form; +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_orphans_form_validate($form, &$form_state) { + $check_count = array_filter($form_state['values']['authors']); + if ($form_state['triggering_element']['#value'] == t('Delete Selected') && count($check_count) == 0) { + form_set_error('', t('No items selected.')); + } +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_orphans_form_submit($form, &$form_state) { + $authors = $names = array(); + // Filter out unchecked authors + if ($form_state['triggering_element']['#value'] == t('Delete Selected')) { + $authors = array_filter($form_state['values']['authors']); + } + elseif ($form_state['triggering_element']['#value'] == t('Delete ALL')) { + $authors = drupal_map_assoc(array_keys($form_state['values']['authors'])); + } + + $names = array_intersect_key($form_state['values']['names'], $authors); + $del_names = implode('; ', $names); + + db_delete('biblio_contributor_data') + ->condition('cid', $authors, 'IN') + ->execute(); + + drupal_set_message(t('The orphaned authors (@author_list) have been deleted.', array('@author_list' => $del_names))); + +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + * @return multitype:NULL + */ +function biblio_admin_keyword_orphans_form($form, $form_state) { + $orphans = $keywords = $options = array(); + + $base = variable_get('biblio_base', 'biblio'); + + $header = array( + 'keyword' => t('Keyword') + ); + + $query = db_select('biblio_keyword', 'bk'); + $active_kids = $query + ->fields('bk', array('kid')) + ->groupBy('kid') + ->execute() + ->fetchCol(); + + $query = db_select('biblio_keyword_data', 'bkd'); + $all_kids = $query + ->fields('bkd', array('kid')) + ->groupBy('kid') + ->execute() + ->fetchCol(); + + $orphans = array_diff($all_kids, $active_kids); + + if (count($orphans)) { + $query = db_select('biblio_keyword_data', 'bkd')->extend('PagerDefault')->limit(50); + $query->fields('bkd'); // SELECT * FROM {biblio_contributor_data} + $query->condition('kid', $orphans, 'IN'); + $result = $query->execute(); //pager_query('SELECT * FROM {biblio_keyword_data} WHERE kid NOT IN (SELECT kid FROM {biblio_keyword} GROUP BY kid)', 50); + foreach ($result as $keyword) { + $options[$keyword->kid] = array( + 'keyword' => array( + 'data' => array( + '#type' => 'link', + '#title' => $keyword->word, + '#href' => $base . '/keywords/' . $keyword->kid . '/edit', + ), + ), + ); + } + } + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Delete'), + '#disabled' => (!count($options)), + '#submit' => array('biblio_admin_keyword_orphans_form_submit'), + ); + $form['words'] = array( + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options, + '#empty' => t('No orphaned keywords.'), + ); + + $form['pager'] = array('#markup' => theme('pager')); + + return $form; +} +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_keyword_orphans_form_validate($form, &$form_state) { + $check_count = array_filter($form_state['values']['words']); + if (count($check_count) == 0) { + form_set_error('', t('No items selected.')); + } +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + */ +function biblio_admin_keyword_orphans_form_submit($form, &$form_state) { + + $keywords = array_filter($form_state['values']['words']); + db_delete('biblio_keyword_data') + ->condition('kid', $keywords, 'IN') + ->execute(); + + drupal_set_message(t('%count orphaned keywords have been deleted.', array('%count' => count($keywords)))); + +} + +/** + * @param unknown_type $form + * @param unknown_type $form_state + * @param unknown_type $keyword_id + * @return multitype:string number NULL + */ +function biblio_admin_keyword_edit_form($form, &$form_state, $keyword_id) { + $options = array(); + $keywords = array(); + $destination = NULL; + + $keyword = db_query('SELECT * FROM {biblio_keyword_data} bkd WHERE bkd.kid = :kid ', array(':kid' => $keyword_id))->fetchObject(); + + $base = variable_get('biblio_base', 'biblio'); +// $path = (strpos($_GET['q'], 'config')) ? 'admin/config/content/biblio/keywords' : $base . '/keywords'; + + if (isset($_GET['destination'])) { + $destination = $_GET['destination']; + } + if (!$destination && isset($form_state['complete form']['#action'])) { + $action = drupal_parse_url($form_state['complete form']['#action']); + $destination = isset($action['query']['destination']) ? $action['query']['destination'] : NULL; + } + if (!$destination) $destination = $base . '/keywords'; + + $form_state['redirect'] = $destination; + + $form['kid'] = array( + '#type' => 'value', + '#value' => $keyword_id + ); + $form['word'] = array( + '#type' => 'textfield', + '#title' => t('Keyword'), + '#default_value' => $keyword->word, + '#size' => 100, + '#weight' => -10, + '#required' => TRUE, + '#maxlength' => 255 + ); + + + $result = db_query("SELECT kd.word, kd.kid, count(*) as use_count FROM {biblio_keyword_data} kd + LEFT JOIN {biblio_keyword} bk on bk.kid = kd.kid + WHERE LOWER(word) LIKE LOWER(:word) + AND kd.kid <> :kid + GROUP BY kd.kid, kd.word", array(':word' => '%%' . drupal_substr($keyword->word, 0, 5) . '%%', ':kid' => $keyword_id)); + + foreach ($result as $keyword) { + $keywords[] = $keyword; + } + + if (isset($form_state['biblio_add_merge_keywords'])) { + $keywords = array_merge($keywords, $form_state['biblio_add_merge_keywords']); + } + + foreach ($keywords as $keyword) { + $options[$keyword->kid] = array( + 'keyword' => array( + 'data' => array( + '#type' => 'link', + '#title' => $keyword->word . ' (' . $keyword->use_count .')', + '#href' => $destination . '/'. $keyword->kid . '/edit', + '#options' => array('query' => array('destination' => $destination)), + ), + ), + ); + } + + $form['merge'] = array( + '#type' => 'fieldset', + '#title' => t('Keyword Merge'), + '#description' => t('If you wish to consolodate references to multiple keywords into single reference to: !kw, select the others from the list below. This will remove the selected keywords from the database and replace references to them with a reference to: !kw. You should only do this if you are sure the other keywords represent the same keyword as the one being edited.', array('!kw' => $keyword->word)), + '#weight' => 5, + '#collapsible' => TRUE, + '#collapsed' => FALSE, + // '#theme' => 'biblio_admin_keyword_merge_fieldset' + ); + + $header = array('keyword' => t('Similar keywords ')); + + $form['merge']['merge_words'] = array( + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options, + '#empty' => t('No similar keywords automatically detected, use the search box below to manually add others.'), + '#prefix' => '' . check_markup($node->biblio_abst_f) . "\n"; + if ($node->biblio_notes) + $output .= '
' . $popup_data . ''; + +} + +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 d72257b2ddc2 -r a75ead649730 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:18:21 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
";
+ $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 d72257b2ddc2 -r a75ead649730 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:18:21 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 d72257b2ddc2 -r a75ead649730 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:18:21 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 d72257b2ddc2 -r a75ead649730 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:18:21 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 d72257b2ddc2 -r a75ead649730 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:18:21 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 d72257b2ddc2 -r a75ead649730 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:18:21 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 d72257b2ddc2 -r a75ead649730 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:18:21 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 d72257b2ddc2 -r a75ead649730 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:18:21 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 '
' . $popup_data . ''; +} + +function _biblio_bibtex_import($entries, $terms = array(), $batch = FALSE, $session_id = NULL, $save = TRUE) { + $nids = array(); + $dups = array(); + + foreach ($entries as $entry) { + $node = new stdClass(); + $node->biblio_contributors = array(); + $node->biblio_type = _biblio_bibtex_type_map($entry['bibtexEntryType'], 'import'); + switch ($entry['bibtexEntryType']) { + case 'mastersthesis': + $node->biblio_type_of_work = 'masters'; + break; + case 'phdthesis': + $node->biblio_type_of_work = 'phd'; + break; + } + if (!empty($entry['author'])) { + // split on ' and ' + $author_array = preg_split("/\s(and|&)\s/i", trim($entry['author'])); + foreach ($author_array as $key => $author) { + // discard braces as biblio uses its own heuristic to split up human names, + // and the braces get in the way + $author = str_replace(array('{', '}'), array('', ''), $author); + $node->biblio_contributors[]= array('name' => $author, 'auth_category' => 1, 'auth_type' => _biblio_get_auth_type(1, $node->biblio_type)); + } + } + + $node->biblio_citekey = (!empty($entry['bibtexCitation'])) ? $entry['bibtexCitation'] : NULL; + if (!empty($entry['editor'])) { + $author_array = preg_split("/\s(and|&)\s/i", trim($entry['editor'])); + foreach ($author_array as $key => $author) { + // discard braces as biblio uses its own heuristic to split up human names, + // and the braces get in the way + $author = str_replace(array('{', '}'), array('', ''), $author); + $node->biblio_contributors[]= array('name' => $author, 'auth_category' => 2, 'auth_type' => _biblio_get_auth_type(2, $node->biblio_type)); + } + } + + $node->biblio_secondary_title = (!empty($entry['journal'])) ? $entry['journal'] : NULL; + if (!empty($entry['booktitle'])) $node->biblio_secondary_title = $entry['booktitle']; + if (!empty($entry['series'])) { + if (!empty($entry['booktitle'])) { + $node->biblio_tertiary_title = $entry['series']; + } + else { + $node->biblio_secondary_title = $entry['series']; + } + } + $node->biblio_volume = (!empty($entry['volume'])) ? $entry['volume'] : NULL; + $node->biblio_number = (!empty($entry['number'])) ? $entry['number'] : NULL; + $node->biblio_year = (!empty($entry['year'])) ? $entry['year'] : NULL; + $node->biblio_notes = (!empty($entry['note'])) ? $entry['note'] : NULL; + $node->biblio_date = (!empty($entry['month'])) ? $entry['month'] : NULL; + $node->biblio_pages = (!empty($entry['pages'])) ? $entry['pages'] : NULL; + $node->biblio_publisher = (!empty($entry['publisher'])) ? $entry['publisher'] : NULL; + if (!empty($entry['organization'])) $node->biblio_publisher = $entry['organization']; + if (!empty($entry['school'])) $node->biblio_publisher = $entry['school']; + if (!empty($entry['institution'])) $node->biblio_publisher = $entry['institution']; + $node->title = (!empty($entry['title'])) ? $entry['title'] : NULL; + $node->biblio_type_of_work .= (!empty($entry['type'])) ? $entry['type'] : NULL; + $node->biblio_edition = (!empty($entry['edition'])) ? $entry['edition'] : NULL; + $node->biblio_section = (!empty($entry['chapter'])) ? $entry['chapter'] : NULL; + $node->biblio_place_published = (!empty($entry['address'])) ? $entry['address'] : NULL; + $node->biblio_abst_e = (!empty($entry['abstract'])) ? $entry['abstract'] : NULL; + if (!empty($entry['keywords'])) { + if (strpos($entry['keywords'], ';')) { + $entry['keywords'] = str_replace(';', ',', $entry['keywords']); + } + $node->biblio_keywords = explode(',', $entry['keywords']); + } + $node->biblio_isbn = (!empty($entry['isbn'])) ? $entry['isbn'] : NULL; + $node->biblio_issn = (!empty($entry['issn'])) ? $entry['issn'] : NULL; + $node->biblio_url = (!empty($entry['url'])) ? $entry['url'] : NULL; + $node->biblio_doi = (!empty($entry['doi'])) ? $entry['doi'] : NULL; + if (module_exists('biblio_pm')) { + $node->biblio_pubmed_id = (!empty($entry['pmid'])) ? $entry['pmid'] : NULL; + $node->biblio_pubmed_md5 = ''; + } + + $node->biblio_bibtex_md5 = md5(serialize($node)); + $node->biblio_import_type = 'bibtex'; + + if (!($dup = biblio_bibtex_check_md5($node->biblio_bibtex_md5))) { + if ($save) { + biblio_save_node($node, $terms, $batch, $session_id, $save); + $nids[] = (!empty($node->nid))? $node->nid : NULL; + } + else { // return the whole node if we are not saveing to the DB (used for the paste function on the input form) + $nids[] = $node; + } + } + else { + $dups[] = $dup; + } + } + return array($nids, $dups); +} +/** + * Export data in bibtex format. + * + * @param $result + * a database result set pointer + * @return + * none + */ +function _biblio_bibtex_export($node) { + static $converter = NULL; + + $bibtex = ''; + $type = "article"; + $journal = $series = $booktitle = $school = $organization = $institution = NULL; + $type = _biblio_bibtex_type_map($node->biblio_type); + switch ($node->biblio_type) { + case 100 : + $series = $node->biblio_secondary_title; + $organization = $node->biblio_publisher; + break; + case 101 : + case 103 : + $booktitle = $node->biblio_secondary_title; + $organization = $node->biblio_publisher; + $series = $node->biblio_tertiary_title; + break; + case 108 : + $school = $node->biblio_publisher; + $node->biblio_publisher = NULL; + if (stripos($node->biblio_type_of_work, 'masters')) { + $type = "mastersthesis"; + } + break; + case 109 : + $institution = $node->biblio_publisher; + $node->biblio_publisher = NULL; + break; + case 102 : + default: + $journal = $node->biblio_secondary_title; + break; + } + + $bibtex .= '@' . $type . ' {'; + $bibtex .= ($node->biblio_citekey) ? $node->biblio_citekey : ""; + $bibtex .= _biblio_bibtex_format_entry('title', $node->title); + $bibtex .= _biblio_bibtex_format_entry('journal', $journal); + $bibtex .= _biblio_bibtex_format_entry('booktitle', $booktitle); + $bibtex .= _biblio_bibtex_format_entry('series', $series); + $bibtex .= _biblio_bibtex_format_entry('volume', $node->biblio_volume); + $bibtex .= _biblio_bibtex_format_entry('number', $node->biblio_number); + $bibtex .= _biblio_bibtex_format_entry('year', $node->biblio_year); + $bibtex .= _biblio_bibtex_format_entry('note', $node->biblio_notes); + $bibtex .= _biblio_bibtex_format_entry('month', $node->biblio_date); + $bibtex .= _biblio_bibtex_format_entry('pages', $node->biblio_pages); + $bibtex .= _biblio_bibtex_format_entry('publisher', $node->biblio_publisher); + $bibtex .= _biblio_bibtex_format_entry('school', $school); + $bibtex .= _biblio_bibtex_format_entry('organization', $organization); + $bibtex .= _biblio_bibtex_format_entry('institution', $institution); + $bibtex .= _biblio_bibtex_format_entry('type', $node->biblio_type_of_work); + $bibtex .= _biblio_bibtex_format_entry('edition', $node->biblio_edition); + $bibtex .= _biblio_bibtex_format_entry('chapter', $node->biblio_section); + $bibtex .= _biblio_bibtex_format_entry('address', $node->biblio_place_published); + $bibtex .= _biblio_bibtex_format_entry('abstract', $node->biblio_abst_e); + + $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); + $bibtex .= _biblio_bibtex_format_entry('keywords', implode(', ', $kw_array)); + } + + $bibtex .= _biblio_bibtex_format_entry('isbn', $node->biblio_isbn); + $bibtex .= _biblio_bibtex_format_entry('issn', $node->biblio_issn); + $bibtex .= _biblio_bibtex_format_entry('doi', $node->biblio_doi); + $bibtex .= _biblio_bibtex_format_entry('url', $node->biblio_url); + + if (!empty ($node->upload) && count($node->upload['und']) && user_access('view uploaded files')) { + foreach ($node->upload['und'] as $file) { + $attachments[] = file_create_url($file['uri']); + } + $bibtex .= _biblio_bibtex_format_entry('attachments', implode(' , ', $attachments)); + } + + $a = $e = $authors = array(); + if ($authors = biblio_get_contributor_category($node->biblio_contributors, 1)) { + foreach ($authors as $auth) $a[] = trim($auth['name']); + } + if ($authors = biblio_get_contributor_category($node->biblio_contributors, 2)) { + foreach ($authors as $auth) $e[] = trim($auth['name']); + } + $a = implode(' and ', $a); + $e = implode(' and ', $e); + if (!empty ($a)) $bibtex .= _biblio_bibtex_format_entry('author', $a); + if (!empty ($e)) $bibtex .= _biblio_bibtex_format_entry('editor', $e); + $bibtex .= "\n}\n"; + + + //now convert any special characters to the latex equivelents... + if (!isset($converter)) { + module_load_include('php', 'biblio_bibtex', 'PARSEENTRIES'); + include_once(drupal_get_path('module', 'biblio_bibtex') . '/transtab_unicode_bibtex.inc.php'); + $converter = new PARSEENTRIES(); + } + $bibtex = $converter->searchReplaceText(_biblio_bibtex_get_transtab(), $bibtex, FALSE); + + return $bibtex; +} + +function _biblio_bibtex_format_entry($key, $value) { + return !empty($value) ? ",\n\t$key = {" . $value . "}" : ''; +} + +function _biblio_bibtex_type_map($type, $direction = 'export') { + static $map = array(); + if (empty($map)) { + $map = biblio_get_map('type_map', 'bibtex'); + } + if ($direction == 'export') { + return ($type = array_search($type, $map)) ? $type : 'article'; + } + else { + return (isset($map[$type])) ? $map[$type] : 129; //return the biblio type or 129 (Misc) if type not found + } +} +function biblio_bibtex_bibtex_map_reset($type = NULL) { + module_load_include('install', 'biblio_bibtex', 'biblio_bibtex'); + _reset_bibtex_map($type); +} + +function biblio_bibtex_check_md5($md5) { + static $bibtex_md5s = array(); + if (empty($bibtex_md5s)) { + $result = db_query("SELECT * FROM {biblio_bibtex} "); + foreach ($result as $row ) { + $bibtex_md5s[$row->biblio_bibtex_md5] = $row->nid; + } + } + if (isset($bibtex_md5s[$md5])) { + return $bibtex_md5s[$md5]; + } + else { + $bibtex_md5s[$md5] = TRUE; // gaurd against duplicates in the same import + return; + } +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/bibtexParse/transtab_latex_unicode.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/bibtexParse/transtab_latex_unicode.inc.php Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,256 @@ + for more info about Unicode and transtab. +function get_transtab_latex_unicode() { +return array( + '\\$\\\\#\\$' => "#", + "\\\\%" => "%", + "\\\\&" => "&", + "(? " ", + "\\{\\\\textexclamdown\\}" => "¡", + "\\{\\\\textcent\\}" => "¢", + "\\{\\\\textsterling\\}" => "£", + "\\{\\\\textyen\\}" => "¥", + "\\{\\\\textbrokenbar\\}" => "¦", + "\\{\\\\textsection\\}" => "§", + "\\{\\\\textasciidieresis\\}" => "¨", + "\\{\\\\textcopyright\\}" => "©", + "\\{\\\\textordfeminine\\}" => "ª", + "\\{\\\\guillemotleft\\}" => "«", + "\\{\\\\textlnot\\}" => "¬", + "\\{\\\\textregistered\\}" => "®", + "\\{\\\\textasciimacron\\}" => "¯", + "\\{\\\\textdegree\\}" => "°", + "\\{\\\\textpm\\}" => "±", + "\\{\\\\texttwosuperior\\}" => "²", + "\\{\\\\textthreesuperior\\}" => "³", + "\\{\\\\textasciiacute\\}" => "´", + "\\{\\\\textmu\\}" => "µ", + "\\{\\\\textparagraph\\}" => "¶", + "\\{\\\\textperiodcentered\\}" => "·", + "\\{\\\\c\\\\ \\}" => "¸", + "\\{\\\\textonesuperior\\}" => "¹", + "\\{\\\\textordmasculine\\}" => "º", + "\\{\\\\guillemotright\\}" => "»", + "\\{\\\\textonequarter\\}" => "¼", + "\\{\\\\textonehalf\\}" => "½", + "\\{\\\\textthreequarters\\}" => "¾", + "\\{\\\\textquestiondown\\}" => "¿", + "\\{?\\\\`\\{?A\\}?\\}?" => "À", + "\\{?\\\\'\\{?A\\}?\\}?" => "Á", + "\\{?\\\\\\^\\{?A\\}?\\}?" => "Â", + "\\{?\\\\~\\{?A\\}?\\}?" => "Ã", + "\\{?\\\\\"\\{?A\\}?\\}?" => "Ä", + "\\\\AA\\ +" => "Å", + "\\{?\\\\r\s\\{?A\\}?\\}?" => "Å", + "\\{?\\\\AE\\}?" => "Æ", + "\\{?\\\\c\sC\\}?" => "Ç", + "\\{?\\\\`\\{?E\\}?\\}?" => "È", + "\\{?\\\\'\\{?E\\}?\\}?" => "É", + "\\{?\\\\\\^\\{?E\\}?\\}?" => "Ê", + "\\{?\\\\\"\\{?E\\}?\\}?" => "Ë", + "\\{?\\\\`\\{?I\\}?\\}?" => "Ì", + "\\{?\\\\'\\{?I\\}?\\}?" => "Í", + "\\{?\\\\\\^\\{?I\\}?\\}?" => "Î", + "\\{?\\\\\"\\{?I\\}?\\}?" => "Ï", + "\\{?\\\\DH\\}?" => "Ð", + "\\{?\\\\~\\{?N\\}?\\}?" => "Ñ", + "\\{?\\\\`\\{?O\\}?\\}?" => "Ò", + "\\{?\\\\'\\{?O\\}?\\}?" => "Ó", + "\\{?\\\\\\^\\{?O\\}?\\}?" => "Ô", + "\\{?\\\\~\\{?O\\}?\\}?" => "Õ", + "\\{?\\\\\"\\{?O\\}?\\}?" => "Ö", + "\\{?\\\\texttimes\\}?" => "×", + "\\\\O\\ +" => "Ø", + "\\{?\\\\O\\}?" => "Ø", + "\\{?\\\\`\\{?U\\}?\\}?" => "Ù", + "\\{?\\\\'\\{?U\\}?\\}?" => "Ú", + "\\{?\\\\\\^\\{?U\\}?\\}?" => "Û", + "\\{?\\\\\"\\{?U\\}?\\}?" => "Ü", + "\\{?\\\\'\\{?Y\\}?\\}?" => "Ý", + "\\{?\\\\TH\\}?" => "Þ", + "\\{?\\\\ss\\{?\\}?\\}?" => "ß", + "\\{?\\\\`\\{?a\\}?\\}?" => "à", + "\\{?\\\\'\\{?a\\}?\\}?" => "á", + "\\{?\\\\\\^\\{?a\\}?\\}?" => "â", + "\\{?\\\\~\\{?a\\}?\\}?" => "ã", + "\\{?\\\\\"\\{?a\\}?\\}?" => "ä", + "\\\\aa\\ +" => "å", + "\\{?\\\\r\s\\{?a\\}?\\}?" => "å", + "\\{?\\\\ae\\}?" => "æ", + "\\{?\\\\c\\{?c\\}?\\}?" => "ç", + "\\{?\\\\`\\{?e\\}?\\}?" => "è", + "\\{?\\\\'\\{?e\\}?\\}?" => "é", + "\\{?\\\\\\^\\{?e\\}?\\}?" => "ê", + "\\{?\\\\\"\s?\\{?e\\}?\\}?" => "ë", + "\\{?\\\\`\\{?i\\}?\\}?" => "ì", + "\\{?\\\\'\\{?i\\}?\\}?" => "í", + "\\{?\\\\\\^\\{?i\\}?\\}?" => "î", + "\\{?\\\\\"\\{?i\\}?\\}?" => "ï", + "\\{?\\\\dh\\}?" => "ð", + "\\{?\\\\~\\{?n\\}?\\}?" => "ñ", + "\\{?\\\\`\\{?o\\}?\\}?" => "ò", + "\\{?\\\\'\\{?o\\}?\\}?" => "ó", + "\\{?\\\\\\^\\{?o\\}?\\}?" => "ô", + "\\{?\\\\~\\{?o\\}?\\}?" => "õ", + "\\{?\\\\\"\\{?o\\}?\\}?" => "ö", + "\\{?\\\\textdiv\\}?" => "÷", + "\\\\o\\ +" => "ø", + "\\{?\\\\o\\}?" => "ø", + "\\{?\\\\`\\{?u\\}?\\}?" => "ù", + "\\{?\\\\'\\{?u\\}?\\}?" => "ú", + "\\{?\\\\\\^\\{?u\\}?\\}?" => "û", + "\\{?\\\\\"\\{?u\\}?\\}?" => "ü", + "\\{?\\\\'\\{?y\\}?\\}?" => "ý", + "\\{?\\\\th\\}?" => "þ", + "\\{?\\\\\"\\{?y\\}?\\}?" => "ÿ", + "\\{?\\\\u\\{?A\\}?\\}?" => "Ă", + "\\{?\\\\u\\{?a\\}?\\}?" => "ă", +// "\\{?\\\\k\\{?A\\}?||}?" => "Ą", + "\\{?\\\\k\\{?a\\}?\\}?" => "ą", + "\\{?\\\\'\\{?C\\}?\\}?" => "Ć", + "\\{?\\\\'\\{?c\\}?\\}?" => "ć", + "\\{?\\\\v\\{?C\\}?\\}?" => "Č", + "\\{?\\\\v\\{?c\\}?\\}?" => "č", + "\\{?\\\\v\\{?c\\}?\\}?" => "č", + "\\{?\\\\v\\{?D\\}?\\}?" => "Ď", + "\\{?\\\\v\\{?d\\}?\\}?" => "ď", + "\\{?\\\\DJ\\}?" => "Đ", + "\\{?\\\\dj\\}?" => "đ", + "\\{?\\\\k\\{?E\\}?\\}?" => "Ę", + "\\{?\\\\k\\{?e\\}?\\}?" => "ę", + "\\{?\\\\v\\{?E\\}?\\}?" => "Ě", + "\\{?\\\\v\\{?e\\}?\\}?" => "ě", + "\\{?\\\\u\s?\\{?e\\}?\\}?" => "ĕ", + "\\{?\\\\u\\{?G\\}?\\}?" => "Ğ", + "\\{?\\\\u\\{?g\\}?\\}?" => "ğ", + "\\{?\\\\.\\{?g\\}?\\}?" => "ġ", + "\\{?\\\\.\\{?I\\}?\\}?" => "İ", + "\\\\'\\{?\\\\i\\}?" => "í", + "\\{?\\\\i\\}?" => "ı", + "\\{?\\\\'\\{?L\\}?\\}?" => "Ĺ", +// "\\{?\\\\'\\{?l\\}?||}?" => "ĺ", + "\\{?\\\\v\\{?L\\}?\\}?" => "Ľ", + "\\{?\\\\v\\{?l\\}?\\}?" => "ľ", + "\\{?\\\\L\\}?" => "Ł", + "\\{?\\\\l\\}?" => "ł", + "\\{?\\\\'\\{?N\\}?\\}?" => "Ń", + "\\{?\\\\'\\{?n\\}?\\}?" => "ń", + "\\{?\\\\v\\{?N\\}?\\}?" => "Ň", + "\\{?\\\\v\\{?n\\}?\\}?" => "ň", + "\\{?\\\\NG\\}?" => "Ŋ", + "\\{?\\\\ng\\}?" => "ŋ", + "\\{?\\\\H\\{?O\\}?\\}?" => "Ő", + "\\{?\\\\H\\{?o\\}?\\}?" => "ő", + "\\{?\\\\OE\\}?" => "Œ", + "\\{?\\\\oe\\}?" => "œ", + "\\{?\\\\'\\{?R\\}?\\}?" => "Ŕ", + "\\{?\\\\'\\{?r\\}?\\}?" => "ŕ", + "\\{?\\\\v\\{?R\\}?\\}?" => "Ř", + "\\{?\\\\v\\{?r\\}?\\}?" => "ř", + "\\{?\\\\'\\{?S\\}?\\}?" => "Ś", + "\\{?\\\\'\\{?s\\}?\\}?" => "ś", + "\\{?\\\\c\\{?S\\}?\\}?" => "Ş", + "\\{?\\\\c\\{?s\\}?\\}?" => "ş", + "\\{?\\\\v\\{?S\\}?\\}?" => "Š", + "\\{?\\\\v\\{?s\\}?\\}?" => "š", + "\\{?\\\\c\\{?T\\}?\\}?" => "Ţ", + "\\{?\\\\c\\{?t\\}?\\}?" => "ţ", + "\\{?\\\\v\\{?T\\}?\\}?" => "Ť", + "\\{?\\\\v\\{?t\\}?\\}?" => "ť", + "\\{?\\\\r\\{?U\\}?\\}?" => "Ů", + "\\{?\\\\r\\{?u\\}?\\}?" => "ů", + "\\{?\\\\H\\{?U\\}?\\}?" => "Ű", + "\\{?\\\\H\\{?u\\}?\\}?" => "ű", + "\\{?\\\\\"\\{?Y\\}?\\}?" => "Ÿ", + "\\{?\\\\'\\{?Z\\}?\\}?" => "Ź", + "\\{?\\\\'\\{?z\\}?\\}?" => "ź", + "\\{?\\\\.\\{?Z\\}?\\}?" => "Ż", + "\\{?\\\\.\\{?z\\}?\\}?" => "ż", + "\\{?\\\\v\\{?Z\\}?\\}?" => "Ž", + "\\{?\\\\v\\{?z\\}?\\}?" => "ž", + "\\{?\\\\textflorin\\}?" => "ƒ", + "\\{?\\\\textasciicircum\\}?" => "ˆ", + "\\{?\\\\textacutedbl\\}?" => "˝", + "\\{?\\\\textendash\\}?|--" => "–", + "\\{?\\\\textemdash\\}?|---" => "—", + "\\{?\\\\textbardbl\\}?" => "‖", + "\\{?\\\\textunderscore\\}?" => "‗", + "\\{?\\\\textquoteleft\\}?" => "‘", + "\\{?\\\\textquoteright\\}?" => "’", + "\\{?\\\\quotesinglbase\\}?" => "‚", + "\\{?\\\\textquotedblleft\\}?" => "“", + "\\{?\\\\textquotedblright\\}?" => "”", + "\\{?\\\\quotedblbase\\}?" => "„", + "\\{?\\\\textdagger\\}?" => "†", + "\\{?\\\\textdaggerdbl\\}?" => "‡", + "\\{?\\\\textbullet\\}?" => "•", + "\\{?\\\\textellipsis\\}?" => "…", + "\\{?\\\\textperthousand\\}?" => "‰", + "\\{?\\\\guilsinglleft\\}?" => "‹", + "\\{?\\\\guilsinglright\\}?" => "›", + "\\{?\\\\textfractionsolidus\\}?" => "⁄", + '\\$\\^\\{0\\}\\$' => "⁰", + '\\$\\^\\{4\\}\\$' => "⁴", + '\\$\\^\\{5\\}\\$' => "⁵", + '\\$\\^\\{6\\}\\$' => "⁶", + '\\$\\^\\{7\\}\\$' => "⁷", + '\\$\\^\\{8\\}\\$' => "⁸", + '\\$\\^\\{9\\}\\$' => "⁹", + '\\$\\^\\{+\\}\\$' => "⁺", + '\\$\\^\\{-\\}\\$' => "⁻", + '\\$\\^\\{=\\}\\$' => "⁼", + '\\$\\^\\{n\\}\\$' => "ⁿ", + '\\$_\\{0\\}\\$' => "₀", + '\\$_\\{1\\}\\$' => "₁", + '\\$_\\{2\\}\\$' => "₂", + '\\$_\\{3\\}\\$' => "₃", + '\\$_\\{4\\}\\$' => "₄", + '\\$_\\{5\\}\\$' => "₅", + '\\$_\\{6\\}\\$' => "₆", + '\\$_\\{7\\}\\$' => "₇", + '\\$_\\{8\\}\\$' => "₈", + '\\$_\\{9\\}\\$' => "₉", + '\\$_\\{+\\}\\$' => "₊", + '\\$_\\{-\\}\\$' => "₋", + '\\$_\\{=\\}\\$' => "₌", + "\\{?\\\\texteuro\\}?" => "€", + "\\{?\\\\textcelsius\\}?" => "℃", + "\\{?\\\\textnumero\\}?" => "№", + "\\{?\\\\textcircledP\\}?" => "℗", + "\\{?\\\\textservicemark\\}?" => "℠", + "\\{?\\\\texttrademark\\}?" => "™", + "\\{?\\\\textohm\\}?" => "Ω", + "\\{?\\\\textestimated\\}?" => "℮", + "\\{?\\\\textleftarrow\\}?" => "←", + "\\{?\\\\textuparrow\\}?" => "↑", + "\\{?\\\\textrightarrow\\}?" => "→", + "\\{?\\\\textdownarrow\\}?" => "↓", + '\\$\\\\infty\\$' => "∞", + "\\{?\\\\textlangle\\}?" => "〈", + "\\{?\\\\textrangle\\}?" => "〉", + "\\{?\\\\textvisiblespace\\}?" => "␣", + "\\{?\\\\textopenbullet\\}?" => "◦", + "\\{?\\\\Delta\\}?" => "Δ", + "\\{?\\\\iota\\}?" => "ι", + "\\{?\\\\omicron\\}?" =>"ο", + "\\{?\\\\mu\\}?" => "μ", + "\\{?\\\\eta\\}?" => "η", + "\\{?\\\\delta\\}?" => "δ", + "\\{?\\\\varsigma\\}?" => "ς", + "\\{?\\\\Sigma\\}?" => "Σ", + "\\{?\\\\pi\\}?" => "π", + "\\{?\\\\nu\\}?" => "ν", + "\\{?\\\\epsilon\\}?" => "ε", + "\\{?\\\\lambda\\}?" => "λ", + "\\{?\\\\=\\{?o\\}?\\}?" => "ō", +); +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/bibtexParse/transtab_unicode_bibtex.inc.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/bibtexParse/transtab_unicode_bibtex.inc.php Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,849 @@ + for more info about Unicode and transtab. + +function _biblio_bibtex_get_transtab() { + + return array( + "(? '$\\#$', + "(? "\\%", + "(? "\\&", + "(? "{\\textquoteright}", + "(? "{\\textquoteleft}", + " " => "~", + "¡" => "{\\textexclamdown}", + "¢" => "{\\textcent}", + "£" => "{\\textsterling}", + "¥" => "{\\textyen}", + "¦" => "{\\textbrokenbar}", + "§" => "{\\textsection}", + "¨" => "{\\textasciidieresis}", + "©" => "{\\textcopyright}", + "ª" => "{\\textordfeminine}", + "«" => "{\\guillemotleft}", + "¬" => "{\\textlnot}", + "" => "-", + "®" => "{\\textregistered}", + "¯" => "{\\textasciimacron}", + "°" => "{\\textdegree}", + "±" => "{\\textpm}", + "²" => "{\\texttwosuperior}", + "³" => "{\\textthreesuperior}", + "´" => "{\\textasciiacute}", + "µ" => "{\\textmu}", + "¶" => "{\\textparagraph}", + "·" => "{\\textperiodcentered}", + "¸" => "{\\c\\ }", + "¹" => "{\\textonesuperior}", + "º" => "{\\textordmasculine}", + "»" => "{\\guillemotright}", + "¼" => "{\\textonequarter}", + "½" => "{\\textonehalf}", + "¾" => "{\\textthreequarters}", + "¿" => "{\\textquestiondown}", + "À" => "{\\`A}", + "Á" => "{\\'A}", + "Â" => "{\\^A}", + "Ã" => "{\\~A}", + "Ä" => "{\\\"A}", + "Å" => "{\\r A}", + "Æ" => "{\\AE}", + "Ç" => "{\\c C}", + "È" => "{\\`E}", + "É" => "{\\'E}", + "Ê" => "{\\^E}", + "Ë" => "{\\\"E}", + "Ì" => "{\\`I}", + "Í" => "{\\'I}", + "Î" => "{\\^I}", + "Ï" => "{\\\"I}", + "Ð" => "{\\DH}", + "Ñ" => "{\\~N}", + "Ò" => "{\\`O}", + "Ó" => "{\\'O}", + "Ô" => "{\\^O}", + "Õ" => "{\\~O}", + "Ö" => "{\\\"O}", + "×" => "{\\texttimes}", + "Ø" => "{\\O}", + "Ù" => "{\\`U}", + "Ú" => "{\\'U}", + "Û" => "{\\^U}", + "Ü" => "{\\\"U}", + "Ý" => "{\\'Y}", + "Þ" => "{\\TH}", + "ß" => "{\\ss}", + "à" => "{\\`a}", + "á" => "{\\'a}", + "â" => "{\\^a}", + "ã" => "{\\~a}", + "ä" => "{\\\"a}", + "å" => "{\\r a}", + "æ" => "{\\ae}", + "ç" => "{\\c c}", + "è" => "{\\`e}", + "é" => "{\\'e}", + "ê" => "{\\^e}", + "ë" => "{\\\"e}", + "ì" => "{\\`\\i}", + "í" => "{\\'\\i}", + "î" => "{\\^\\i}", + "ï" => "{\\\"\\i}", + "ð" => "{\\dh}", + "ñ" => "{\\~n}", + "ò" => "{\\`o}", + "ó" => "{\\'o}", + "ô" => "{\\^o}", + "õ" => "{\\~o}", + "ö" => "{\\\"o}", + "÷" => "{\\textdiv}", + "ø" => "{\\o}", + "ù" => "{\\`u}", + "ú" => "{\\'u}", + "û" => "{\\^u}", + "ü" => "{\\\"u}", + "ý" => "{\\'y}", + "þ" => "{\\th}", + "ÿ" => "{\\\"y}", + "Ā" => "A", + "ā" => "{\\={a}}", + "Ă" => "{\\u A}", + "ă" => "{\\u a}", + "Ą" => "{\\k A}", + "ą" => "{\\k a}", + "Ć" => "{\\'C}", + "ć" => "{\\'c}", + "Ĉ" => "Ch", + "ĉ" => "ch", + "Ċ" => "C", + "ċ" => "c", + "Č" => "{\\v C}", + "č" => "{\\v c}", + "Ď" => "{\\v D}", + "ď" => "{\\v d}", + "Đ" => "{\\DJ}", + "đ" => "{\\dj}", + "Ē" => "E", + "ē" => "e", + "Ĕ" => "E", + "ĕ" => "e", + "Ė" => "E", + "ė" => "e", + "Ę" => "{\\k E}", + "ę" => "{\\k e}", + "Ě" => "{\\v E}", + "ě" => "{\\v e}", + "Ĝ" => "Gh", + "ĝ" => "gh", + "Ğ" => "{\\u G}", + "ğ" => "{\\u g}", + "Ġ" => "G", + "ġ" => "g", + "Ģ" => "G", + "ģ" => "g", + "Ĥ" => "Hh", + "ĥ" => "hh", + "Ħ" => "H", + "ħ" => "h", + "Ĩ" => "I", + "ĩ" => "i", + "Ī" => "I", + "ī" => "i", + "Ĭ" => "I", + "ĭ" => "i", + "Į" => "I", + "į" => "i", + "İ" => "{\\.I}", + "ı" => "{\\i}", + "IJ" => "IJ", + "ij" => "ij", + "Ĵ" => "Jh", + "ĵ" => "jh", + "Ķ" => "K", + "ķ" => "k", + "ĸ" => "k", + "Ĺ" => "{\\'L}", + "ĺ" => "{\\'l}", + "Ļ" => "L", + "ļ" => "l", + "Ľ" => "{\\v L}", + "ľ" => "{\\v l}", + "Ŀ" => "L·", + "ŀ" => "l·", + "Ł" => "{\\L}", + "ł" => "{\\l}", + "Ń" => "{\\'N}", + "ń" => "{\\'n}", + "Ņ" => "N", + "ņ" => "n", + "Ň" => "{\\v N}", + "ň" => "{\\v n}", + "ʼn" => "'n", + "Ŋ" => "{\\NG}", + "ŋ" => "{\\ng}", + "Ō" => "O", + "ō" => "o", + "Ŏ" => "O", + "ŏ" => "o", + "Ő" => "{\\H O}", + "ő" => "{\\H o}", + "Œ" => "{\\OE}", + "œ" => "{\\oe}", + "Ŕ" => "{\\'R}", + "ŕ" => "{\\'r}", + "Ŗ" => "R", + "ŗ" => "r", + "Ř" => "{\\v R}", + "ř" => "{\\v r}", + "Ś" => "{\\'S}", + "ś" => "{\\'s}", + "Ŝ" => "Sh", + "ŝ" => "sh", + "Ş" => "{\\c S}", + "ş" => "{\\c s}", + "Š" => "{\\v S}", + "š" => "{\\v s}", + "Ţ" => "{\\c T}", + "ţ" => "{\\c t}", + "Ť" => "{\\v T}", + "ť" => "{\\v t}", + "Ŧ" => "T", + "ŧ" => "t", + "Ũ" => "U", + "ũ" => "u", + "Ū" => "U", + "ū" => "u", + "Ŭ" => "U", + "ŭ" => "u", + "Ů" => "{\\r U}", + "ů" => "{\\r u}", + "Ű" => "{\\H U}", + "ű" => "{\\H u}", + "Ų" => "U", + "ų" => "u", + "Ŵ" => "W", + "ŵ" => "w", + "Ŷ" => "Y", + "ŷ" => "y", + "Ÿ" => "{\\\"Y}", + "Ź" => "{\\'Z}", + "ź" => "{\\'z}", + "Ż" => "{\\.Z}", + "ż" => "{\\.z}", + "Ž" => "{\\v Z}", + "ž" => "{\\v z}", + "ſ" => "s", + "ƒ" => "{\\textflorin}", + "Ș" => "S", + "ș" => "s", + "Ț" => "T", + "ț" => "t", + "ʹ" => "'", + "ʻ" => "'", + "ʼ" => "'", + "ʽ" => "'", + "ˆ" => "{\\textasciicircum}", + "ˈ" => "'", + "ˉ" => "-", + "ˌ" => ",", + "ː" => ":", + "˚" => "o", + "˜" => "\\~{}", + "˝" => "{\\textacutedbl}", + "ʹ" => "'", + "͵" => ",", + ";" => ";", + "Ḃ" => "B", + "ḃ" => "b", + "Ḋ" => "D", + "ḋ" => "d", + "Ḟ" => "F", + "ḟ" => "f", + "Ṁ" => "M", + "ṁ" => "m", + "Ṗ" => "P", + "ṗ" => "p", + "Ṡ" => "S", + "ṡ" => "s", + "Ṫ" => "T", + "ṫ" => "t", + "Ẁ" => "W", + "ẁ" => "w", + "Ẃ" => "W", + "ẃ" => "w", + "Ẅ" => "W", + "ẅ" => "w", + "Ỳ" => "Y", + "ỳ" => "y", + " " => " ", + " " => " ", + " " => " ", + " " => " ", + " " => " ", + " " => " ", + " " => " ", + " " => " ", + " " => " ", + " " => " ", + "‐" => "-", + "‑" => "-", + "‒" => "-", + "–" => "{\\textendash}", + "—" => "{\\textemdash}", + "―" => "--", + "‖" => "{\\textbardbl}", + "‗" => "{\\textunderscore}", + "‘" => "{\\textquoteleft}", + "’" => "{\\textquoteright}", + "‚" => "{\\quotesinglbase}", + "‛" => "'", + "“" => "{\\textquotedblleft}", + "”" => "{\\textquotedblright}", + "„" => "{\\quotedblbase}", + "‟" => "\"", + "†" => "{\\textdagger}", + "‡" => "{\\textdaggerdbl}", + "•" => "{\\textbullet}", + "‣" => ">", + "․" => ".", + "‥" => "..", + "…" => "{\\textellipsis}", + "‧" => "-", + " " => " ", + "‰" => "{\\textperthousand}", + "′" => "'", + "″" => "\"", + "‴" => "'''", + "‵" => "`", + "‶" => "``", + "‷" => "```", + "‹" => "{\\guilsinglleft}", + "›" => "{\\guilsinglright}", + "‼" => "!!", + "‾" => "-", + "⁃" => "-", + "⁄" => "{\\textfractionsolidus}", + "⁈" => "?!", + "⁉" => "!?", + "⁊" => "7", + "⁰" => '$^{0}$', + "⁴" => '$^{4}$', + "⁵" => '$^{5}$', + "⁶" => '$^{6}$', + "⁷" => '$^{7}$', + "⁸" => '$^{8}$', + "⁹" => '$^{9}$', + "⁺" => '$^{+}$', + "⁻" => '$^{-}$', + "⁼" => '$^{=}$', + "⁽" => '$^{(}$', + "⁾" => '$^{)}$', + "ⁿ" => '$^{n}$', + "₀" => '$_{0}$', + "₁" => '$_{1}$', + "₂" => '$_{2}$', + "₃" => '$_{3}$', + "₄" => '$_{4}$', + "₅" => '$_{5}$', + "₆" => '$_{6}$', + "₇" => '$_{7}$', + "₈" => '$_{8}$', + "₉" => '$_{9}$', + "₊" => '$_{+}$', + "₋" => '$_{-}$', + "₌" => '$_{=}$', + "₍" => '$_{(}$', + "₎" => '$_{)}$', + "€" => "{\\texteuro}", + "℀" => "a/c", + "℁" => "a/s", + "℃" => "{\\textcelsius}", + "℅" => "c/o", + "℆" => "c/u", + "℉" => "F", + "ℓ" => "l", + "№" => "{\\textnumero}", + "℗" => "{\\textcircledP}", + "℠" => "{\\textservicemark}", + "℡" => "TEL", + "™" => "{\\texttrademark}", + "Ω" => "{\\textohm}", + "K" => "K", + "Å" => "A", + "℮" => "{\\textestimated}", + "⅓" => " 1/3", + "⅔" => " 2/3", + "⅕" => " 1/5", + "⅖" => " 2/5", + "⅗" => " 3/5", + "⅘" => " 4/5", + "⅙" => " 1/6", + "⅚" => " 5/6", + "⅛" => " 1/8", + "⅜" => " 3/8", + "⅝" => " 5/8", + "⅞" => " 7/8", + "⅟" => " 1/", + "Ⅰ" => "I", + "Ⅱ" => "II", + "Ⅲ" => "III", + "Ⅳ" => "IV", + "Ⅴ" => "V", + "Ⅵ" => "VI", + "Ⅶ" => "VII", + "Ⅷ" => "VIII", + "Ⅸ" => "IX", + "Ⅹ" => "X", + "Ⅺ" => "XI", + "Ⅻ" => "XII", + "Ⅼ" => "L", + "Ⅽ" => "C", + "Ⅾ" => "D", + "Ⅿ" => "M", + "ⅰ" => "i", + "ⅱ" => "ii", + "ⅲ" => "iii", + "ⅳ" => "iv", + "ⅴ" => "v", + "ⅵ" => "vi", + "ⅶ" => "vii", + "ⅷ" => "viii", + "ⅸ" => "ix", + "ⅹ" => "x", + "ⅺ" => "xi", + "ⅻ" => "xii", + "ⅼ" => "l", + "ⅽ" => "c", + "ⅾ" => "d", + "ⅿ" => "m", + "←" => "{\\textleftarrow}", + "↑" => "{\\textuparrow}", + "→" => "{\\textrightarrow}", + "↓" => "{\\textdownarrow}", + "↔" => "<->", + "⇐" => "<=", + "⇒" => "=>", + "⇔" => "<=>", + "−" => "-", + "∕" => "/", + "∖" => "\\", + "∗" => "*", + "∘" => "o", + "∙" => ".", + "∞" => '$\\infty$', + "∣" => "|", + "∥" => "||", + "∶" => ":", + "∼" => "\\~{}", + "≠" => "/=", + "≡" => "=", + "≤" => "<=", + "≥" => ">=", + "≪" => "<<", + "≫" => ">>", + "⊕" => "(+)", + "⊖" => "(-)", + "⊗" => "(x)", + "⊘" => "(/)", + "⊢" => "|-", + "⊣" => "-|", + "⊦" => "|-", + "⊧" => "|=", + "⊨" => "|=", + "⊩" => "||-", + "⋅" => ".", + "⋆" => "*", + "⋕" => '$\\#$', + "⋘" => "<<<", + "⋙" => ">>>", + "⋯" => "...", + "〈" => "{\\textlangle}", + "〉" => "{\\textrangle}", + "␀" => "NUL", + "␁" => "SOH", + "␂" => "STX", + "␃" => "ETX", + "␄" => "EOT", + "␅" => "ENQ", + "␆" => "ACK", + "␇" => "BEL", + "␈" => "BS", + "␉" => "HT", + "␊" => "LF", + "␋" => "VT", + "␌" => "FF", + "␍" => "CR", + "␎" => "SO", + "␏" => "SI", + "␐" => "DLE", + "␑" => "DC1", + "␒" => "DC2", + "␓" => "DC3", + "␔" => "DC4", + "␕" => "NAK", + "␖" => "SYN", + "␗" => "ETB", + "␘" => "CAN", + "␙" => "EM", + "␚" => "SUB", + "␛" => "ESC", + "␜" => "FS", + "␝" => "GS", + "␞" => "RS", + "␟" => "US", + "␠" => "SP", + "␡" => "DEL", + "␣" => "{\\textvisiblespace}", + "" => "NL", + "␥" => "///", + "␦" => "?", + "①" => "(1)", + "②" => "(2)", + "③" => "(3)", + "④" => "(4)", + "⑤" => "(5)", + "⑥" => "(6)", + "⑦" => "(7)", + "⑧" => "(8)", + "⑨" => "(9)", + "⑩" => "(10)", + "⑪" => "(11)", + "⑫" => "(12)", + "⑬" => "(13)", + "⑭" => "(14)", + "⑮" => "(15)", + "⑯" => "(16)", + "⑰" => "(17)", + "⑱" => "(18)", + "⑲" => "(19)", + "⑳" => "(20)", + "⑴" => "(1)", + "⑵" => "(2)", + "⑶" => "(3)", + "⑷" => "(4)", + "⑸" => "(5)", + "⑹" => "(6)", + "⑺" => "(7)", + "⑻" => "(8)", + "⑼" => "(9)", + "⑽" => "(10)", + "⑾" => "(11)", + "⑿" => "(12)", + "⒀" => "(13)", + "⒁" => "(14)", + "⒂" => "(15)", + "⒃" => "(16)", + "⒄" => "(17)", + "⒅" => "(18)", + "⒆" => "(19)", + "⒇" => "(20)", + "⒈" => "1.", + "⒉" => "2.", + "⒊" => "3.", + "⒋" => "4.", + "⒌" => "5.", + "⒍" => "6.", + "⒎" => "7.", + "⒏" => "8.", + "⒐" => "9.", + "⒑" => "10.", + "⒒" => "11.", + "⒓" => "12.", + "⒔" => "13.", + "⒕" => "14.", + "⒖" => "15.", + "⒗" => "16.", + "⒘" => "17.", + "⒙" => "18.", + "⒚" => "19.", + "⒛" => "20.", + "⒜" => "(a)", + "⒝" => "(b)", + "⒞" => "(c)", + "⒟" => "(d)", + "⒠" => "(e)", + "⒡" => "(f)", + "⒢" => "(g)", + "⒣" => "(h)", + "⒤" => "(i)", + "⒥" => "(j)", + "⒦" => "(k)", + "⒧" => "(l)", + "⒨" => "(m)", + "⒩" => "(n)", + "⒪" => "(o)", + "⒫" => "(p)", + "⒬" => "(q)", + "⒭" => "(r)", + "⒮" => "(s)", + "⒯" => "(t)", + "⒰" => "(u)", + "⒱" => "(v)", + "⒲" => "(w)", + "⒳" => "(x)", + "⒴" => "(y)", + "⒵" => "(z)", + "Ⓐ" => "(A)", + "Ⓑ" => "(B)", + "Ⓒ" => "(C)", + "Ⓓ" => "(D)", + "Ⓔ" => "(E)", + "Ⓕ" => "(F)", + "Ⓖ" => "(G)", + "Ⓗ" => "(H)", + "Ⓘ" => "(I)", + "Ⓙ" => "(J)", + "Ⓚ" => "(K)", + "Ⓛ" => "(L)", + "Ⓜ" => "(M)", + "Ⓝ" => "(N)", + "Ⓞ" => "(O)", + "Ⓟ" => "(P)", + "Ⓠ" => "(Q)", + "Ⓡ" => "(R)", + "Ⓢ" => "(S)", + "Ⓣ" => "(T)", + "Ⓤ" => "(U)", + "Ⓥ" => "(V)", + "Ⓦ" => "(W)", + "Ⓧ" => "(X)", + "Ⓨ" => "(Y)", + "Ⓩ" => "(Z)", + "ⓐ" => "(a)", + "ⓑ" => "(b)", + "ⓒ" => "(c)", + "ⓓ" => "(d)", + "ⓔ" => "(e)", + "ⓕ" => "(f)", + "ⓖ" => "(g)", + "ⓗ" => "(h)", + "ⓘ" => "(i)", + "ⓙ" => "(j)", + "ⓚ" => "(k)", + "ⓛ" => "(l)", + "ⓜ" => "(m)", + "ⓝ" => "(n)", + "ⓞ" => "(o)", + "ⓟ" => "(p)", + "ⓠ" => "(q)", + "ⓡ" => "(r)", + "ⓢ" => "(s)", + "ⓣ" => "(t)", + "ⓤ" => "(u)", + "ⓥ" => "(v)", + "ⓦ" => "(w)", + "ⓧ" => "(x)", + "ⓨ" => "(y)", + "ⓩ" => "(z)", + "⓪" => "(0)", + "─" => "-", + "━" => "=", + "│" => "|", + "┃" => "|", + "┄" => "-", + "┅" => "=", + "┆" => "|", + "┇" => "|", + "┈" => "-", + "┉" => "=", + "┊" => "|", + "┋" => "|", + "┌" => "+", + "┍" => "+", + "┎" => "+", + "┏" => "+", + "┐" => "+", + "┑" => "+", + "┒" => "+", + "┓" => "+", + "└" => "+", + "┕" => "+", + "┖" => "+", + "┗" => "+", + "┘" => "+", + "┙" => "+", + "┚" => "+", + "┛" => "+", + "├" => "+", + "┝" => "+", + "┞" => "+", + "┟" => "+", + "┠" => "+", + "┡" => "+", + "┢" => "+", + "┣" => "+", + "┤" => "+", + "┥" => "+", + "┦" => "+", + "┧" => "+", + "┨" => "+", + "┩" => "+", + "┪" => "+", + "┫" => "+", + "┬" => "+", + "┭" => "+", + "┮" => "+", + "┯" => "+", + "┰" => "+", + "┱" => "+", + "┲" => "+", + "┳" => "+", + "┴" => "+", + "┵" => "+", + "┶" => "+", + "┷" => "+", + "┸" => "+", + "┹" => "+", + "┺" => "+", + "┻" => "+", + "┼" => "+", + "┽" => "+", + "┾" => "+", + "┿" => "+", + "╀" => "+", + "╁" => "+", + "╂" => "+", + "╃" => "+", + "╄" => "+", + "╅" => "+", + "╆" => "+", + "╇" => "+", + "╈" => "+", + "╉" => "+", + "╊" => "+", + "╋" => "+", + "╌" => "-", + "╍" => "=", + "╎" => "|", + "╏" => "|", + "═" => "=", + "║" => "|", + "╒" => "+", + "╓" => "+", + "╔" => "+", + "╕" => "+", + "╖" => "+", + "╗" => "+", + "╘" => "+", + "╙" => "+", + "╚" => "+", + "╛" => "+", + "╜" => "+", + "╝" => "+", + "╞" => "+", + "╟" => "+", + "╠" => "+", + "╡" => "+", + "╢" => "+", + "╣" => "+", + "╤" => "+", + "╥" => "+", + "╦" => "+", + "╧" => "+", + "╨" => "+", + "╩" => "+", + "╪" => "+", + "╫" => "+", + "╬" => "+", + "╭" => "+", + "╮" => "+", + "╯" => "+", + "╰" => "+", + "╱" => "/", + "╲" => "\\", + "╳" => "X", + "╼" => "-", + "╽" => "|", + "╾" => "-", + "╿" => "|", + "○" => "o", + "◦" => "{\\textopenbullet}", + "★" => "*", + "☆" => "*", + "☒" => "X", + "☓" => "X", + "☹" => ":-(", + "☺" => ":-)", + "☻" => "(-:", + "♭" => "b", + "♯" => '$\\#$', + "✁" => '$\\%<$', + "✂" => '$\\%<$', + "✃" => '$\\%<$', + "✄" => '$\\%<$', + "✌" => "V", + "✓" => "v", + "✔" => "V", + "✕" => "x", + "✖" => "x", + "✗" => "X", + "✘" => "X", + "✙" => "+", + "✚" => "+", + "✛" => "+", + "✜" => "+", + "✝" => "+", + "✞" => "+", + "✟" => "+", + "✠" => "+", + "✡" => "*", + "✢" => "+", + "✣" => "+", + "✤" => "+", + "✥" => "+", + "✦" => "+", + "✧" => "+", + "✩" => "*", + "✪" => "*", + "✫" => "*", + "✬" => "*", + "✭" => "*", + "✮" => "*", + "✯" => "*", + "✰" => "*", + "✱" => "*", + "✲" => "*", + "✳" => "*", + "✴" => "*", + "✵" => "*", + "✶" => "*", + "✷" => "*", + "✸" => "*", + "✹" => "*", + "✺" => "*", + "✻" => "*", + "✼" => "*", + "✽" => "*", + "✾" => "*", + "✿" => "*", + "❀" => "*", + "❁" => "*", + "❂" => "*", + "❃" => "*", + "❄" => "*", + "❅" => "*", + "❆" => "*", + "❇" => "*", + "❈" => "*", + "❉" => "*", + "❊" => "*", + "❋" => "*", + "ff" => "ff", + "fi" => "fi", + "fl" => "fl", + "ffi" => "ffi", + "ffl" => "ffl", + "ſt" => "st", + "st" => "st" + ); + +} \ No newline at end of file diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/crossref/biblio.crossref.client.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/crossref/biblio.crossref.client.php Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,326 @@ +setDOI($doi); + $this->setUserID($id); + $this->setURL(self::BASE_URL); + $this->field_map = array(); + $this->type_map = array(); + } + + public function setURL($url) { + $this->url = $url; + } + + public function setDOI($doi) { + $this->doi = $doi; + } + + public function getDOI() { + return $this->doi; + } + + public function setUserID($id) { + $this->pid = $id; + } + + public function getUserID() { + return $this->pid; + } + + public function getQuery() { + return $this->query; + } + + public function fetch() { + $this->query = $this->url . '?pid=' . $this->pid . '&noredirect=true&format=unixref&id=doi%3A' . $this->doi; + + $request_options = array('method' => 'POST'); + $result = drupal_http_request($this->query, $request_options); + + if ($result->code != 200) { + drupal_set_message(t('HTTP error: !error when trying to contact crossref.org for XML input', array('!error' => $result->code)),'error'); + return; + } + if (empty($result->data)) { + drupal_set_message(t('Did not get any data from crossref.org'),'error'); + return; + } + $sxml = @simplexml_load_string($result->data); + if (!isset($sxml->doi_record)) { + drupal_set_message(t('Failed to retrieve data for doi ') . $this->doi, 'error'); + return; + } + + if ($error = (string)$sxml->doi_record->crossref->error) { + drupal_set_message($error,'error'); + return; + } + $this->nodes = array(); + $this->parser = drupal_xml_parser_create($result->data); + // use case-folding so we are sure to find the tag in + xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, FALSE); + xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, TRUE); + + xml_set_object($this->parser, $this); + xml_set_element_handler($this->parser, 'unixref_startElement', 'unixref_endElement'); + xml_set_character_data_handler($this->parser, 'unixref_characterData'); + + if(!xml_parse($this->parser, $result->data)){ + drupal_set_message(sprintf("XML error: %s at line %d", + xml_error_string(xml_get_error_code($this->parser)), + xml_get_current_line_number($this->parser)),'error'); + } + + xml_parser_free($this->parser); + + return $this->node; + } + + + function unixref_startElement($parser, $name, $attrs) { + switch ($name) { + case 'doi_record' : + $this->node = array(); + $this->node['biblio_contributors'] = array(); + $this->contributors = array(); + $this->element = $name; + break; + case 'book': + case 'journal': + case 'standard': + case 'conference': + case 'report-paper': + case 'dissertation': + case 'database': + case 'sa_component': + $this->node['biblio_type'] = $this->_unixref_type_map($name); + $this->element = $name; + break; + case 'journal_article': + case 'conference_paper': + case 'content_item': + case 'report-paper_metadata': + case 'standard_metadata': + case 'database_date': + case 'component': + $this->node['year'] = ''; + $this->node['doi'] = ''; + $this->element = $name; + break; + case 'person_name' : + $this->auth_category = $this->_unixref_get_contributor_category($attrs['contributor_role']); + if (!isset($this->contrib_count)) $this->contrib_count = 0; + $this->element = $name; + break; + case 'organization': + if (!isset($this->org_count)) $this->org_count = 0; + $this->element = $name; + break; + case 'issn': + if (isset($attrs['media_type']) ) $this->attribute = $attrs['media_type']; + $this->element = $name; + break; + case 'isbn': + if (isset($attrs['media_type']) ) $this->attribute = $attrs['media_type']; + $this->element = $name; + break; + case 'i': // HTML font style tags + case 'b': + case 'u': + case 'sub': + case 'sup': + $this->unixref_characterData(NULL, ' <' . $name . '>'); + break; + case 'doi_data': + $this->doi_data = TRUE; + break; + default : + $this->element = $name; + } + + } + + function unixref_decode(&$item, $key) { + $item = html_entity_decode($item, NULL, 'UTF-8'); + } + + function unixref_endElement($parser, $name) { + switch ($name) { + case 'doi_record' : + $this->node['biblio_contributors'] += $this->contributors; + array_walk_recursive($this->node, array($this,'unixref_decode') ); + $this->node['biblio_crossref_id'] = $this->getDOI(); + $this->node['biblio_crossref_md5'] = md5(serialize($this->node)); + $this->nodes[] = $this->node; //biblio_save_node($node, $batch, $session_id, $save_node); + break; + case 'person_name' : + $this->contributors[$this->contrib_count]['auth_type'] = _biblio_get_auth_type($this->auth_category, $this->node['biblio_type']); + $this->contributors[$this->contrib_count]['auth_category'] = $this->auth_category; + $this->contributors[$this->contrib_count]['name'] = + $this->contributors[$this->contrib_count]['lastname']; + if (isset($this->contributors[$this->contrib_count]['firstname'])) { + $this->contributors[$this->contrib_count]['name'] .= + ', ' . $this->contributors[$this->contrib_count]['firstname']; + } + + $this->auth_category = ''; + $this->contrib_count++; + break; + case 'organization' : + $this->contributors[$this->contrib_count]['auth_type'] = _biblio_get_auth_type(5, $this->node['biblio_type']); + $this->contributors[$this->contrib_count]['auth_category'] = 5; + $this->contrib_count++; + break; + case 'pages': + if (isset($this->node['biblio_first_page'])) $this->node['biblio_pages'] = $this->node['biblio_first_page']; + if (isset($this->node{'biblio_last_page'})) $this->node['biblio_pages'] .= ' - ' . $this->node['biblio_last_page']; + break; + case 'publication_date': + + break; + case 'journal_issue': + case 'journal_article': + if (!isset($this->node['biblio_date']) || empty($this->node['biblio_date'])) { + $day = !empty($this->node['day']) ? $this->node['day'] : 1; + $month = !empty($this->node['month']) ? $this->node['month'] : 1; + $year = !empty($this->node['year']) ? $this->node['year'] : 0; + if ($year) { + $this->node['biblio_date'] = date("M-d-Y", mktime(0, 0, 0, $day, $month, $year)); + } + } + if ((!isset($this->node['biblio_year']) || empty($this->node['biblio_year'])) && isset($this->node['year'])) { + $this->node['biblio_year'] = $this->node['year']; + } + break; + case 'conference_paper': + case 'content_item': + case 'report-paper_metadata': + case 'standard_metadata': + case 'database_date': + case 'component': + if ((!isset($this->node['biblio_year']) || empty($this->node['biblio_year'])) && isset($this->node['year'])) { + $this->node['biblio_year'] = $this->node['year']; + unset($this->node['year']); + } +// $this->node['biblio_doi'] = $this->node['doi']; + break; + case 'issn': + case 'isbn': + $this->attribute = ''; + break; + case 'i': // HTML font style tags + case 'b': + case 'u': + case 'sub': + case 'sup': + $this->unixref_characterData(NULL, '' . $name . '> '); + break; + case 'doi_data': + $this->doi_data = FALSE; + break; + default : + } + } + + function unixref_characterData($parser, $data) { + $data = htmlspecialchars_decode($data); + if (trim($data)) { + switch ($this->element) { + case 'surname' : + $this->contributors[$this->contrib_count]['lastname'] = $data; + break; + case 'given_name' : + $this->contributors[$this->contrib_count]['firstname'] = $data; + break; + case 'suffix': + $this->contributors[$this->contrib_count]['suffix'] = $data; + break; + case 'affiliation' : + $this->contributors[$this->contrib_count]['affiliation'] = $data; + break; + case 'organization': + $this->contributors[$this->contrib_count]['name'] = $data; + break; + case 'year': + case 'month': + case 'day': + $this->node[$this->element] = $data; + break; + case 'issn': + case 'isbn': + if ($this->attribute == 'print') { + if ($field = $this->_unixref_field_map(trim($this->element))) { + $this->_set_data($field, $data); + } + } + break; + case 'doi': + if ($this->doi_data) { + if ($field = $this->_unixref_field_map(trim($this->element))) { + $this->_set_data($field, $data); + } + } + break; + case 'resource': + if ($this->doi_data) { + $this->_set_data('biblio_url', $data); + } + break; + + default: + if ($field = $this->_unixref_field_map(trim($this->element))) { + $this->_set_data($field, $data); + } + + } + } + } + function _set_data($field, $data) { + $this->node[$field] = (isset($this->node[$field]) ? $this->node[$field] . $data : $data); + } + /* + * map a unixref XML field to a biblio field + */ + function _unixref_field_map($field) { + if (empty($this->field_map)) { + $this->field_map = unserialize(db_query("SELECT field_map FROM {biblio_type_maps} WHERE format='crossref'")->fetchField()); + } + return (isset($this->field_map[$field])) ? $this->field_map[$field]: FALSE; + } + + function _unixref_type_map($type) { + if (empty($this->type_map)) { + $this->type_map = unserialize(db_query("SELECT type_map FROM {biblio_type_maps} WHERE format='crossref'")->fetchField()); + } + return (isset($this->type_map[$type]))?$this->type_map[$type]:129; //return the biblio type or 129 (Misc) if type not found + } + + function _unixref_get_contributor_category($role) { + if ($role == 'author') return 1; + if ($role == 'editor') return 2; + if ($role == 'chair') return 3; + if ($role == 'translator') return 4; + return NULL; + } +} \ No newline at end of file diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/crossref/biblio_crossref.info --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/crossref/biblio_crossref.info Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,13 @@ +name = Biblio - Crossref +description = Provides DOI lookup and import to the Biblio module. +core = 7.x +package = Biblio +dependencies[] = biblio +files[] = biblio.crossref.client.php + +; 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 d72257b2ddc2 -r a75ead649730 modules/biblio/modules/crossref/biblio_crossref.install --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/crossref/biblio_crossref.install Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,151 @@ +condition('format', 'crossref') + ->execute(); + } +} + +function biblio_crossref_enable() { + biblio_crossref_set_system_weight(); +} + +function biblio_crossref_set_system_weight() { + db_update('system') + ->fields(array('weight' => 20)) + ->condition('name', 'biblio_crossref') + ->execute(); +} +function _save_crossref_maps() { + $typemap = _get_crossref_type_map(); + $typenames = _get_crossref_type_names(); + $fieldmap = _get_crossref_field_map(); + $maps = array_merge($typemap, $typenames, $fieldmap); + biblio_save_map($maps); +} +function _reset_crossref_map($type) { + $count = db_query("SELECT COUNT(*) FROM {biblio_type_maps} WHERE format='crossref'")->fetchField(); + if ($count && $type) { //update + $function = '_get_crossref_' . $type; + if (!function_exists($function)) return; + $map = $function(); + db_update('biblio_type_maps') + ->fields($map) + ->condition('format', 'crossref') + ->execute(); + } + else { // install +// db_query("DELETE FROM {biblio_type_maps} WHERE format='crossref'"); + db_delete('biblio_type_maps') + ->condition('format', 'crossref') + ->execute(); + _save_crossref_maps(); + } +} + +function _get_crossref_type_map() { + $map['type_map'] = serialize( + array( + 'error' => 0, + 'book' => 100, // Book + 'journal' => 102, // Journal Article + 'standard' => 129, // Generic + 'conference' => 103, // conference_paper + 'report-paper' => 109, // Report + 'dissertation' => 108, // Thesis + 'database' => 125, // online database + 'sa_component' => 129 + ) + ); + $map['format'] = 'crossref'; + return $map; +} + +function _get_crossref_type_names() { + $map['type_names'] = serialize( + array( + 'error' => 'Error', + 'book' => 'Book', + 'journal' => 'Journal Article', + 'standard' => 'Generic', + 'conference' => 'Conference Paper', + 'report-paper' => 'Report', + 'dissertation' => 'Thesis', + 'database' => 'Online database', + 'sa_component' => 'SA Component', + ) + ); + $map['format'] = 'crossref'; + return $map; +} + +function _get_crossref_field_map() { + $map['field_map'] = serialize( + array( + 'publisher_place' => 'biblio_place_published', + 'publisher_name' => 'biblio_publisher', + 'volume' => 'biblio_volume', + 'number' => 'biblio_number', + 'issue' => 'biblio_issue', + 'edition_number' => 'biblio_edition', + 'section' => 'biblio_section', + 'doi' => 'biblio_doi', + 'title' => 'title', + 'isbn' => 'biblio_isbn', + 'issn' => 'biblio_issn', + 'first_page' => 'biblio_first_page', + 'last_page' => 'biblio_last_page', + // Journal metadata + 'full_title' => 'biblio_secondary_title', + 'abbrev_title' => 'biblio_short_title', + // Conference metadata + 'conference_location' => 'biblio_place_published', + 'conference_name' => 'biblio_secondary_title', + 'conference_acronym' => 'biblio_short_title', + // Proceedings metadata + 'proceedings_title' => 'biblio_secondary_title', + 'year' => 'year', + 'month' => 'month', + 'day' => 'day', + 'degree' => 'biblio_type_of_work', + 'error' => 'error', + 'language' => 'biblio_lang', + ) + ); + + $map['format'] = 'crossref'; + return $map; + +} + +/** + * Implementation of hook_schema(). + * + * Note: Pro Drupal Development models use of t() to translate 'description' + * for field definitions, but Drupal core does not use them. We follow core. + */ +function biblio_crossref_schema() { + $schema = array(); + $schema['biblio_crossref'] = array( + 'fields' => array( + 'nid' => array('type' => 'int', 'not null' => TRUE), + 'biblio_crossref_md5' => array('type' => 'char', 'length' => 32, 'not null' => TRUE), + 'biblio_crossref_id' => array('type' => 'char', 'length' => 255, 'not null' => TRUE), + ), + 'primary key' => array('nid'), + ); + return $schema; +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/crossref/biblio_crossref.module --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/crossref/biblio_crossref.module Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,168 @@ + 5 && !$form_state['submitted'] && !isset($form['#node']->nid)) { + $form['biblio_doi_lookup'] = array( + '#type' => 'fieldset', + '#title' => t('DOI Lookup'), + '#weight' => -20, + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $have_pid = variable_get('biblio_crossref_pid', ''); + $user_pid = (isset($user->data['biblio_crossref_pid']) && !empty($user->data['biblio_crossref_pid'])) ? $user->data['biblio_crossref_pid'] : ''; + if (variable_get('biblio_show_crossref_profile_form', '1') && !empty($user_pid)) { + $have_pid = $user_pid; + } + if (empty($have_pid)) { + $form['biblio_doi_lookup']['doi_register'] = array( + '#prefix' => '
', + '#suffix' => '
', + '#markup' => t('!url1 and then enter your CrossRef UserID in the "CrossRef Login Information" section of your account profile !url2', array('!url1' => l(t('You need to register with CrossRef'), 'http://www.crossref.org/requestaccount/', array('attributes' => array('target' => '_blank'), 'absolue' => TRUE)), '!url2' => l(t('here...'), "user/$user->uid/edit"))), + ); + } + + $form['biblio_doi_lookup']['doi_data'] = array( + '#type' => 'textfield', + '#title' => t('DOI'), + '#required' => FALSE, + '#default_value' => (isset($form_state['values']['doi_data']) ? $form_state['values']['doi_data'] : ''), + '#description' => t('Enter a DOI name in the form: 10.1000/123456'), + '#disabled' => empty($have_pid), + '#size' => 60, + '#maxlength' => 255, + '#weight' => -4 + ); + $form['biblio_doi_lookup']['doi_submit'] = array( + '#type' => 'submit', + '#disabled' => empty($have_pid), + '#value' => t('Populate using DOI'), + '#submit' => array('biblio_crossref_form_biblio_node_form_submit') + ); + } + $biblio_crossref_id = (isset($form_state['values']['biblio_crossref_id'])) ? $form_state['values']['biblio_crossref_id'] : ''; + $biblio_crossref_md5 = (isset($form_state['values']['biblio_crossref_md5'])) ? $form_state['values']['biblio_crossref_md5'] : ''; + $form['biblio_crossref_id'] = array('#type' => 'value', '#value' => $biblio_crossref_id); + $form['biblio_crossref_md5'] = array('#type' => 'value', '#value' => $biblio_crossref_md5); +} + +function biblio_crossref_form_biblio_node_form_submit($form, &$form_state) { + global $user; + $node_data = array(); + if (strlen($doi = $form_state['values']['doi_data'])) { + if (($doi_start = strpos($form_state['values']['doi_data'], '10.')) !== FALSE) { + if (!($dup = biblio_crossref_check_doi($doi))) { + $crossref_pid = variable_get('biblio_crossref_pid', ''); + $user_pid = (isset($user->data['biblio_crossref_pid']) && !empty($user->data['biblio_crossref_pid'])) ? $user->data['biblio_crossref_pid'] : ''; + if (variable_get('biblio_show_crossref_profile_form', '1') && !empty($user_pid)) { + $crossref_pid = $user_pid; + } + + if (empty($crossref_pid)) { + form_set_error('doi_data', l(t('You need to register with CrossRef'), 'http://www.crossref.org/requestaccount/', array('attributes' => array('target' => '_blank'), 'absolue' => TRUE)) . ' ' . t('and then enter your CrossRef UserID in the "CrossRef Login Information" section of your account profile !url', array('!url' => l(t('here...'), "user/$user->uid/edit")))); + return; + } + + module_load_include('php', 'biblio_crossref', 'biblio.crossref.client'); + $client = new BiblioCrossRefClient($doi, $crossref_pid); + $node_data = $client->fetch(); + + if (!empty($node_data)) { + $form_state['values'] = array_merge($form_state['values'], $node_data); + $form_state['input']['biblio_type'] = $form_state['biblio_type'] = $node_data['biblio_type']; + } + else { + form_set_error('doi_data', ''); + } + } + else { + $message = t('The DOI that you are trying to import already exists in the database, see !url', array('!url' => l('node/' . $dup, 'node/' . $dup))); + form_set_error('doi_data', $message); + } + } + else { + form_set_error('doi_data', t('This does not appear to be a valid DOI name, it should start with "10."')); + } + } + $form_state['rebuild'] = TRUE; + return; +} + +function biblio_crossref_check_doi($doi) { + return db_query("SELECT nid FROM {biblio_crossref} WHERE biblio_crossref_id = :doi", array(':doi' => $doi))->fetchField(); +} + +function biblio_crossref_biblio_lookup_link_settings() { + return array('crossref' => t('DOI')); +} +function biblio_crossref_biblio_mapper_options() { + return array( + 'crossref' => array( + 'title' => t('CrossRef XML'), + 'export' => FALSE, + ), + ); +} + +function biblio_crossref_biblio_lookup_link($node) { + $show_link = variable_get('biblio_lookup_links', array('crossref' => TRUE)); + if (empty($show_link['crossref']) || !isset($node) || (!isset($node->biblio_crossref_id) && empty($node->biblio_doi))) { + return; + } + if ($node->type == 'biblio') { + $doi = isset($node->biblio_crossref_id) ? $node->biblio_crossref_id : $node->biblio_doi; + if ( ($doi_start = strpos($doi, '10.')) !== FALSE) { + $doi = substr($doi, $doi_start); + } + $link = 'http://dx.doi.org/' . $doi; + return array('biblio_crossref' => array( + 'title' => t('DOI'), + 'href' => $link, + 'attributes' => array('title' => t("Click to view the CrossRef listing for this node")), + )); + } + return ; + } + + +function biblio_crossref_node_view($node, $view_mode, $langcode) { + if ($node->type == 'biblio' && (isset($node->biblio_crossref_id) || !empty($node->biblio_doi))) { + switch ($view_mode) { + case 'full': + case 'teaser': + $node->content['links']['biblio_crossref'] = array( + '#links' => biblio_crossref_biblio_lookup_link($node), + '#attributes' => array('class' => array('links', 'inline')), + ); + } + } +} + +function biblio_crossref_node_delete($node) { + if ($node->type != 'biblio') return; + db_delete('biblio_crossref') + ->condition('nid', $node->nid) + ->execute(); +} + +function biblio_crossref_node_insert($node) { + if ($node->type != 'biblio') return; + if (empty($node->biblio_crossref_id)) return; + drupal_write_record('biblio_crossref', $node); +} + +function biblio_crossref_node_load($nodes, $types) { + $result = db_query('SELECT nid, biblio_crossref_id FROM {biblio_crossref} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes))); + foreach ($result as $record) { + $nodes[$record->nid]->biblio_crossref_id = $record->biblio_crossref_id; + } +} +function biblio_crossref_crossref_map_reset($type = NULL) { + module_load_include('install', 'biblio_crossref', 'biblio_crossref'); + _reset_crossref_map($type); +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/endnote/biblio_tagged.info --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/endnote/biblio_tagged.info Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,13 @@ +name = Biblio - EndNote Tagged +description = Provides EndNote tagged file import and export to the Biblio module. +core = 7.x +package = Biblio +dependencies[] = biblio +files[] = views/biblio_handler_field_export_link_tagged.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 d72257b2ddc2 -r a75ead649730 modules/biblio/modules/endnote/biblio_tagged.install --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/endnote/biblio_tagged.install Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,196 @@ +condition('format', 'tagged') + ->execute(); + } +} + +function biblio_tagged_enable() { + biblio_tagged_set_system_weight(); +} + +function biblio_tagged_set_system_weight() { + db_update('system') + ->fields(array('weight' => 22)) + ->condition('name', 'biblio_tagged') + ->execute(); +} + +function _get_tagged_type_map() { + $map['type_map'] = serialize( + array( + "Journal Article" => 102, + "Conference Paper" => 103, + "Conference Proceedings" => 104, + "Report" => 109, + "Book" => 100, + "Edited Book" => 100, + "Book Section" => 101, + "Thesis" => 108, + "Patent" => 119, + "Generic" => 129, + "Newspaper Article" => 105, + "Magazine Article" => 106, + "Web Page" => 107, + "Film or Broadcast" => 110, + "Artwork" => 112, + "Audiovisual Material" => 114, + "Hearing" => 115, + "Case" => 116, + "Bill" => 117, + "Statute" => 118, + "Personal Communication" => 120, + "Manuscript" => 121, + "Map" => 122, + "Chart or Table" => 123, + "Unpublished Work" => 124, + "Online Database" => 125, + "Government Document" => 126, + "Classical Work" => 127, + "Legal Rule or Regulation" => 128, + ) + ); + $map['format'] = 'tagged'; + return $map; +} +function _get_tagged_type_names() { + $map['type_names'] = serialize( + array( + "Journal Article" => "Journal Article", + "Conference Paper" => "Conference Paper", + "Conference Proceedings" => "Conference Proceedings", + "Report" => "Report", + "Book" => "Book", + "Edited Book" => "Edited Book", + "Book Section" => "Book Section", + "Thesis" => "Thesis", + "Patent" => "Patent", + "Generic" => "Generic", + "Newspaper Article" => "Newspaper Article", + "Magazine Article" => "Magazine Article", + "Web Page" => "Web Page", + "Film or Broadcast" => "Film or Broadcast", + "Artwork" => "Artwork", + "Audiovisual Material" => "Audiovisual Material", + "Hearing" => "Hearing", + "Case" => "Case", + "Bill" => "Bill", + "Statute" => "Statute", + "Personal Communication" => "Personal Communication", + "Manuscript" => "Manuscript", + "Map" => "Map", + "Chart or Table" => "Chart or Table", + "Unpublished Work" => "Unpublished Work", + "Online Database" => "Online Database", + "Government Document" => "Government Document", + "Classical Work" => "Classical Work", + "Legal Rule or Regulation" => "Legal Rule or Regulation", + ) + ); + + $map['format'] = 'tagged'; + return $map; +} + +function _get_tagged_field_map() { + $map['field_map'] = serialize( + array( + '%B' => 'biblio_secondary_title', + '%C' => 'biblio_place_published', + '%D' => 'biblio_year', + '%F' => 'biblio_label', + '%G' => 'biblio_lang', + '%I' => 'biblio_publisher', + '%J' => 'biblio_secondary_title', + '%K' => 'biblio_keywords', + '%L' => 'biblio_call_number', + '%M' => 'biblio_accession_number', + '%N' => 'biblio_issue', + '%P' => 'biblio_pages', + '%R' => 'biblio_doi', + '%S' => 'biblio_tertiary_title', + '%U' => 'biblio_url', + '%V' => 'biblio_volume', + '%1' => 'biblio_custom1', + '%2' => 'biblio_custom2', + '%3' => 'biblio_custom3', + '%4' => 'biblio_custom4', + '%#' => 'biblio_custom5', + '%$' => 'biblio_custom6', + '%]' => 'biblio_custom7', + '%6' => 'biblio_number_of_volumes', + '%7' => 'biblio_edition', + '%8' => 'biblio_date', + '%9' => 'biblio_type_of_work', + '%?' => '', + '%@' => 'biblio_isbn', + '%<' => 'biblio_research_notes', + '%!' => 'biblio_short_title', + '%&' => 'biblio_section', + '%(' => 'biblio_original_publication', + '%)' => 'biblio_reprint_edition', + '%*' => '', + '%+' => '', + ) + ); + $map['format'] = 'tagged'; + return $map; +} + +function _save_tagged_maps() { + $typemap = _get_tagged_type_map(); + $typenames = _get_tagged_type_names(); + $fieldmap = _get_tagged_field_map(); + $maps = array_merge($typemap, $typenames, $fieldmap); + biblio_save_map($maps); +} + +function _reset_tagged_map($type) { + $count = db_query("SELECT COUNT(*) FROM {biblio_type_maps} WHERE format='tagged'")->fetchField(); + if ($count && $type) { //update + $function = '_get_tagged_' . $type; + if (!function_exists($function)) return; + $map = $function(); + db_update('biblio_type_maps') + ->fields($map) + ->condition('format', 'tagged') + ->execute(); + } + else { // install + db_delete('biblio_type_maps') + ->condition('format', 'tagged') + ->execute(); + _save_tagged_maps(); + } +} +/** + * Implementation of hook_schema(). + * + * Note: Pro Drupal Development models use of t() to translate 'description' + * for field definitions, but Drupal core does not use them. We follow core. + */ +function biblio_tagged_schema() { + $schema = array(); + $schema['biblio_tagged'] = array( + 'fields' => array( + 'nid' => array('type' => 'int', 'not null' => TRUE), + 'biblio_tagged_md5' => array('type' => 'char', 'length' => 32, 'not null' => TRUE), + ), + 'primary key' => array('nid'), + ); + return $schema; +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/endnote/biblio_tagged.module --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/endnote/biblio_tagged.module Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,407 @@ + 2, + 'path' => drupal_get_path('module', 'biblio_tagged') . '/views', + ); +} +/* + * add the tagged 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_tagged', 'biblio_import',...) + */ +function biblio_tagged_biblio_import_options() { + return array('biblio_tagged' => t('EndNote Tagged')); +} +function biblio_tagged_biblio_mapper_options() { + return array( + 'tagged' => array( + 'title' => t('EndNote Tagged'), + 'export' => TRUE, + ) + ); +} + +function biblio_tagged_biblio_export_options() { + return array('tagged' => t('EndNote Tagged')); +} + +function biblio_tagged_node_view($node, $view_mode) { + if ($node->type == 'biblio') { + switch ($view_mode) { + case 'full': + case 'teaser': + $links = biblio_tagged_biblio_export_link($node->nid); + $node->content['links']['biblio_tagged'] = array( + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); + } + } +} + +/** + * Creates a link to export a node (or view) in tagged 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 (tagged) + */ +function biblio_tagged_biblio_export_link($nid = NULL, $filter = array()) { + $show_link = variable_get('biblio_export_links', array('tagged' => TRUE)); + if (!isset($show_link['tagged']) || empty($show_link['tagged']) || !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 EndNote Tagged output"))); + } + else { + $link = array( + 'attributes' => array( + 'title' => t("Click to download the EndNote Tagged formatted file"))); + } + + $link['attributes'] += array('rel' => 'nofollow'); + + $link['href'] = "$base/export/tagged"; + if (!empty($nid)) { + $link['href'] .= '/' . $nid; + } + $link['title'] = t('Tagged'); + + if (empty($nid) && !empty($filter)) { // add any filters which may be on the current page + $link['query'] = $filter; + } + + return array('biblio_tagged' => $link); +} + + +function biblio_tagged_node_delete($node) { + if ($node->type != 'biblio') { + return; + } + db_delete('biblio_tagged') + ->condition('nid', $node->nid) + ->execute(); +} + +function biblio_tagged_node_insert($node) { + if ($node->type != 'biblio' || !isset($node->biblio_tagged_md5)) { + return; + } + drupal_write_record('biblio_tagged', $node); +} + +function biblio_tagged_biblio_import($file, $terms = array(), $batch = FALSE, $session_id = NULL, $save = TRUE, $string = FALSE) { + $nids = array(); + $dups = array(); + list($nids, $dups) = _biblio_tagged_import($file, $terms, $batch, $session_id); + + return array($nids, $dups); +} + +function biblio_tagged_biblio_export($nids) { + if (module_exists('popups') && count($nids)) { + $popup = TRUE; + } + else { + $popup = FALSE; + drupal_add_http_header('Content-type', 'application/x-endnote-refer'); + drupal_add_http_header('Content-Disposition', 'attachment; filename="Drupal-Biblio.enw"'); + } + + $nodes = node_load_multiple($nids, array(), TRUE); + foreach ($nodes as $node) { + if (variable_get('biblio_hide_bibtex_braces', 0) ) { + $node->title = biblio_remove_brace($node->title); + } + + if (!$popup) { + print _biblio_tagged_export($node); + } + else{ + $popup_data .= _biblio_tagged_export($node); + } + } + if ($popup && !empty($popup_data)) return '' . $popup_data . ''; + +} + +/** + * Export data in tagged format. + * + * @param $result + * a database result set pointer + * @return + * none + */ + +function _biblio_tagged_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 EndNote Tagged input"), 'error'); + return; + } + $nids = array(); + $dups = array(); + $ignored_tags = array(); + $node = NULL; + $incite = FALSE; + $node_id = NULL; + $contributors = NULL; + while (!feof($fp)) { + $line = trim(fgets($fp)); + $line_len = strlen($line); + if ($line_len) { + $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); + $value = trim(drupal_substr($line, $start +3)); + } + else { + $value = $line; + } + } + if ($line_len) { // if this is not a blank line + if (!$incite) { + $incite = TRUE; + $node = new stdClass(); + //$node->biblio_contributors = array(); + + } + switch ($tag) { + case '%0' : + $node->biblio_type = _biblio_tagged_type_map($value); + break; + case '%A' : + $node->biblio_contributors[] = array( + 'name' => $value, + 'auth_category' => 1, + 'auth_type' => _biblio_get_auth_type(1, $node->biblio_type)); + break; + case '%E' : + $node->biblio_contributors[] = array( + 'name' => $value, + 'auth_category' => 2, + 'auth_type' => _biblio_get_auth_type(2, $node->biblio_type)); + break; + case '%T' : + $node->title = $value; + break; + case '%Y' : + $node->biblio_contributors[] = array( + 'name' => $value, + 'auth_category' => 3, + 'auth_type' => _biblio_get_auth_type(3, $node->biblio_type)); + break; + case '%?' : + $node->biblio_contributors[] = array( + 'name' => $value, + 'auth_category' => 4, + 'auth_type' => _biblio_get_auth_type(4, $node->biblio_type)); + break; + case '%X' : + $node->biblio_abst_e .= $value; + break; + case '%Z' : + $node->biblio_notes .= $value; + break; + + default : + $field = _biblio_tagged_field_map($tag); + if (!empty($field)) { + $node->$field = $value; + } + else { + if (!in_array($tag, $ignored_tags)) { + $ignored_tags[] = $tag; + } + } + break; + } //end switch + } + else { + $incite = FALSE; + if (!empty($node)) { + _biblio_tagged_save($node, $terms, $batch, $session_id, $nids, $dups); + $node = NULL; + } + + } // end if ($start !== FALSE) + } // end while + + fclose($fp); + + if ($incite && !empty($node)) { // this catches the case where the file ends without a blank line at the end + _biblio_tagged_save($node, $terms, $batch, $session_id, $nids, $dups); + } + + if (!empty($ignored_tags)) { + $ignored_tags = array_unique($ignored_tags); + $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/tagged'))); + } + drupal_set_message($message, 'warning'); + } + + return array($nids, $dups); +} + +function _biblio_tagged_save($node, $terms, $batch, $session_id, &$nids, &$dups) { + $node->biblio_tagged_md5 = md5(serialize($node)); + if (! ($dup = biblio_tagged_check_md5($node->biblio_tagged_md5))) { + biblio_save_node($node, $terms, $batch, $session_id); + if (!empty($node->nid)) $nids[] = $node->nid; + } + else { + $dups[] = $dup; + } +} + +function _biblio_tagged_export($node) { + $export = TRUE; + $tagged = ""; + $tagged .= "%0 " . _biblio_tagged_type_map($node->biblio_type, $export) . "\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)) + $tagged .= "%B " . trim($node->biblio_secondary_title) . "\r\n"; + break; + case 102 : + if (!empty($node->biblio_secondary_title)) + $tagged .= "%J " . trim($node->biblio_secondary_title) . "\r\n"; + break; // journal + } + if (isset($node->biblio_year) && $node->biblio_year < 9998) $tagged .= "%D " . trim($node->biblio_year) . "\r\n"; + if (!empty($node->title)) $tagged .= "%T " . trim($node->title) . "\r\n"; + + foreach (biblio_get_contributor_category($node->biblio_contributors, 1) as $auth) { + $tagged .= "%A " . trim($auth['name']) . "\r\n"; + } + foreach (biblio_get_contributor_category($node->biblio_contributors, 2) as $auth) { + $tagged .= "%E " . trim($auth['name']) . "\r\n"; + } + foreach (biblio_get_contributor_category($node->biblio_contributors, 3) as $auth) { + $tagged .= "%Y " . trim($auth['name']) . "\r\n"; + } + foreach (biblio_get_contributor_category($node->biblio_contributors, 4) as $auth) { + $tagged .= "%? " . 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) { + $tagged .= "%K " . 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); + $tagged .= "%X " . $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)) { + $tagged .= _biblio_tagged_format_entry($field, $node->$field); + } + } + if (!empty ($node->upload) && count($node->upload['und']) && user_access('view uploaded files')) { + foreach ($node->upload['und'] as $file) { + $tagged .= "%> " . file_create_url($file['uri']) . "\r\n"; // insert file here. + } + } + $tagged .= "\r\n"; + return $tagged; +} + +function _biblio_tagged_format_entry($key, $value) { + $reverse = TRUE; + $tag = _biblio_tagged_field_map($key, $reverse); + if (!empty($tag)) { + return "$tag " . trim($value) . "\r\n"; + } + +} + +function _biblio_tagged_type_map($type, $reverse = FALSE) { + static $map = array(); + + if (empty($map)) { + $map = biblio_get_map('type_map', 'tagged'); + } + + 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_tagged_field_map($field, $reverse = FALSE) { + static $fmap = array(); + + if (empty($fmap)) { + $fmap = biblio_get_map('field_map', 'tagged' ); + } + + if ($reverse) { + return ($tag = array_search($field, $fmap)) ? $tag : ''; + } + return (!empty($fmap[$field])) ? $fmap[$field] : ''; + +} + +function biblio_tagged_tagged_map_reset($type = NULL) { + module_load_include('install', 'biblio_tagged', 'biblio_tagged'); + _reset_tagged_map($type); +} + +function biblio_tagged_check_md5($md5) { + static $tagged_md5s = array(); + if (empty($tagged_md5s)) { + $result = db_query("SELECT * FROM {biblio_tagged} "); + foreach ($result as $row ) { + $tagged_md5s[$row->biblio_tagged_md5] = $row->nid; + } + } + if (isset($tagged_md5s[$md5])) { + return $tagged_md5s[$md5]; + } + else { + $tagged_md5s[$md5] = TRUE; // gaurd against duplicates in the same import + return; + } +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/endnote/biblio_xml.info --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/endnote/biblio_xml.info Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,14 @@ +name = Biblio - EndNote XML +description = Provides EndNote XML file import and export to the Biblio module. +core = 7.x +package = Biblio +dependencies[] = biblio +files[] = endnote_xml_parser.inc +files[] = views/biblio_handler_field_export_link_xml.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 d72257b2ddc2 -r a75ead649730 modules/biblio/modules/endnote/biblio_xml.install --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/endnote/biblio_xml.install Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,390 @@ +condition('format', 'endnote8') + ->execute(); + + db_delete('biblio_type_maps') + ->condition('format', 'endnote7') + ->execute(); + } +} + +function biblio_xml_enable() { + biblio_xml_set_system_weight(); +} + +function biblio_xml_set_system_weight() { + db_update('system') + ->fields(array('weight' => 26)) + ->condition('name', 'biblio_xml') + ->execute(); +} + +function _save_xml_maps() { + _save_endnote7_maps(); + _save_endnote8_maps(); +} +function _save_endnote7_maps() { + $format = 'endnote7'; + $typemap = _get_endnote7_type_map(); + $typenames = _get_endnote7_type_names(); + $fieldmap = _get_endnote7_field_map(); + $maps = array_merge($typemap, $typenames, $fieldmap); + biblio_save_map($maps); +} + +function _save_endnote8_maps() { + $typemap = _get_endnote8_type_map(); + $typenames = _get_endnote8_type_names(); + $fieldmap = _get_endnote8_field_map(); + $maps = array_merge($typemap, $typenames, $fieldmap); + biblio_save_map($maps); +} + +function _reset_endnote_xml_map($version, $type) { + $count = db_query("SELECT COUNT(*) FROM {biblio_type_maps} WHERE format=:format", array(':format' => $version))->fetchField(); + if ($count && $type) { //update + $function = '_get_' . $version . '_' . $type; + if (!function_exists($function)) return; + $map = $function(); + drupal_write_record('biblio_type_maps', $map, 'format'); + db_update('biblio_type_maps') + ->fields($map) + ->condition('format', $version) + ->execute(); + } + else { // install + db_delete('biblio_type_maps') + ->condition('format', $version) + ->execute(); + $save_maps = '_save_' . $version . '_maps'; + $save_maps(); + } +} + +function _get_endnote8_type_map() { + $map['type_map'] = serialize( + array( + 2 => 112, // artwork + 3 => 114, // Audio Visual + 4 => 117, // bill + 5 => 101, // Book Section + 6 => 100, // Book + 7 => 116, // case + 9 => 113, // software + 17 => 102, // Journal Article + 10 => 104, // Conference Proceeding + 12 => 107, // web page + 13 => 129, // Generic + 14 => 115, // hearing + 19 => 106, // magazine_article + 20 => 122, // map + 21 => 110, // film + 21 => 111, // broadcast + 23 => 105, // newspaper_article + 25 => 119, // patent + 26 => 120, // personal communication + 27 => 109, // Report + 28 => 129, // Edited Book + 31 => 118, // statute + 32 => 108, // Thesis + 34 => 124, // unpublished + 36 => 121, // manuscript + 37 => 129, // figure + 38 => 123, // chart + 39 => 129, // equation + 43 => 129, // electronic article + 44 => 129, // electronic book + 45 => 125, // online database + 46 => 126, // government_document + 47 => 103, // conference_paper + 48 => 129, // online multimedia + 49 => 127, // Classical Work + 50 => 128, // legal_ruling + 52 => 129, // Dictionary + 53 => 129, // Encyclopedia + 54 => 129, // Grant + ) + ); + $map['format'] = 'endnote8'; + return $map; +} + +function _get_endnote8_type_names() { + $map['type_names'] = serialize( + array( + 2 => 'Artwork', + 3 => 'Audio Visual', + 4 => 'Bill', + 5 => 'Book Section', + 6 => 'Book', + 7 => 'Case', + 9 => 'Software', + 17 => 'Journal Article', + 10 => 'Conference Proceeding', + 12 => 'Web page', + 13 => 'Generic', + 14 => 'Hearing', + 19 => 'Magazine Article', + 20 => 'Map', + 21 => 'Film', + 21 => 'Broadcast', + 23 => 'Newspaper Article', + 25 => 'Patent', + 26 => 'Personal Communication', + 27 => 'Report', + 28 => 'Edited Book', + 31 => 'Statute', + 32 => 'Thesis', + 34 => 'Unpublished', + 36 => 'Manuscript', + 37 => 'Figure', + 38 => 'Chart', + 39 => 'Equation', + 43 => 'Electronic Article', + 44 => 'Electronic Book', + 45 => 'Online Database', + 46 => 'Government Document', + 47 => 'Conference Paper', + 48 => 'Online Multimedia', + 49 => 'Classical Work', + 50 => 'Legal Ruling', + 52 => 'Dictionary', + 53 => 'Encyclopedia', + 54 => 'Grant', + ) + ); + $map['format'] = 'endnote8'; + return $map; +} + +function _get_endnote8_field_map() { + + $map['field_map'] = serialize( + array( + 'source-app' => '', + 'rec-number' => '', + 'ref-type' => 'biblio_type', + 'auth-address' => 'biblio_auth_address', + 'auth-affiliaton' => '', + 'secondary-title' => 'biblio_secondary_title', + 'tertiary-title' => 'biblio_tertiary_title', + 'alt-title' => 'biblio_alternate_title', + 'short-title' => 'biblio_short_title', + 'translated-title' => 'biblio_translated_title', + 'full-title' => 'biblio_secondary_title', + 'abbr-1' => 'biblio_short_title', + 'abbr-2' => '', + 'abbr-3' => '', + 'pages' => 'biblio_pages', + 'volume' => 'biblio_volume', + 'number' => 'biblio_number', + 'issue' => 'biblio_issue', + 'secondary-volume' => '', + 'secondary-issue' => '', + 'num-vols' => 'biblio_number_of_volumes', + 'edition' => 'biblio_edition', + 'section' => 'biblio_section', + 'reprint-edition' => 'biblio_reprint_edition', + 'reprint-status' => '', + 'year' => 'biblio_year', + 'pub-dates' => 'biblio_date', + 'copyright-dates' => '', + 'pub-location' => 'biblio_place_published', + 'publisher' => 'biblio_publisher', + 'orig-pub' => 'biblio_original_publication', + 'isbn' => 'biblio_isbn', + 'accession-num' => 'biblio_accession_number', + 'call-num' => 'biblio_call_number', + 'report-id' => '', + 'coden' => '', + 'electronic-resource-num' => '', + 'abstract' => 'biblio_abst_e', + 'label' => 'biblio_label', + 'image' => '', + 'caption' => '', + 'notes' => 'biblio_notes', + 'research-notes' => 'biblio_research_notes', + 'work-type' => 'biblio_type_of_work', + 'reviewed-item' => '', + 'availability' => '', + 'remote-source' => '', + 'meeting-place' => '', + 'work-location' => '', + 'work-extent' => '', + 'pack-method' => '', + 'size' => '', + 'repro-ratio' => '', + 'remote-database-name' => 'biblio_remote_db_name', + 'remote-database-provider' => 'biblio_remote_db_provider', + 'language' => 'biblio_lang', + 'web-urls' => '', + 'pdf-urls' => '', + 'text-urls' => '', + 'image-urls' => '', + 'related-urls' => 'biblio_url', + 'access-date' => 'biblio_access_date', + 'modified-date' => '', + 'custom1' => 'biblio_custom1', + 'custom2' => 'biblio_custom2', + 'custom3' => 'biblio_custom3', + 'custom4' => 'biblio_custom4', + 'custom5' => 'biblio_custom5', + 'custom6' => 'biblio_custom6', + 'custom7' => 'biblio_custom7', + 'misc1' => '', + 'misc2' => '', + 'misc3' => '', + ) + ); + + $map['format'] = 'endnote8'; + return $map; +} +function _get_endnote7_type_map() { + + $map['type_map'] = serialize( + array( + 0 => 102, // Journal Article + 1 => 100, // Book + 2 => 108, // Thesis + 3 => 103, // Conference Proceedings + 4 => 120, // Personal Communication + 5 => 105, // NewsPaper Article + 6 => 113, // Computer Program + 7 => 101, // Book Section + 8 => 106, // Magazine Article + 9 => 100, // Edited Book + 10 => 109, // Report + 11 => 122, // Map + 12 => 114, // Audiovisual Material + 13 => 112, // Artwork + 15 => 119, // Patent + 16 => 107, // Electronic Source + 17 => 117, // Bill + 18 => 116, // Case + 19 => 115, // Hearing + 20 => 121, // Manuscript + 21 => 110, // Film or Broadcast + 22 => 118, // Statute + 26 => 123, // Chart or Table + 31 => 129 // Generic + ) + ); + $map['format'] = 'endnote7'; + return $map; +} +function _get_endnote7_type_names() { + + $map['type_names'] = serialize( + array( + 0 => 'Journal Article', + 1 => 'Book', + 2 => 'Thesis', + 3 => 'Conference Proceedings', + 4 => 'Personal Communication', + 5 => 'NewsPaper Article', + 6 => 'Computer Program', + 7 => 'Book Section', + 8 => 'Magazine Article', + 9 => 'Edited Book', + 10 => 'Report', + 11 => 'Map', + 12 => 'Audiovisual Material', + 13 => 'Artwork', + 15 => 'Patent', + 16 => 'Electronic Source', + 17 => 'Bill', + 18 => 'Case', + 19 => 'Hearing', + 20 => 'Manuscript', + 21 => 'Film or Broadcast', + 22 => 'Statute', + 26 => 'Chart or Table', + 31 => 'Generic', + ) + ); + $map['format'] = 'endnote7'; + return $map; +} + +function _get_endnote7_field_map() { + + $map['field_map'] = serialize( + array( + 'REFERENCE_TYPE' => 'biblio_type', + 'REFNUM' => '', + 'YEAR' => 'biblio_year', + 'SECONDARY_TITLE' => 'biblio_secondary_title', + 'PLACE_PUBLISHED' => 'biblio_place_published', + 'PUBLISHER' => 'biblio_publisher', + 'VOLUME' => 'biblio_volume', + 'ISSUE' => 'biblio_issue', + 'NUMBER_OF_VOLUMES' => 'biblio_number_of_volumes', + 'NUMBER' => 'biblio_number', + 'PAGES' => 'biblio_pages', + 'SECTION' => 'biblio_section', + 'TERTIARY_TITLE' => 'biblio_tertiary_title', + 'EDITION' => 'biblio_edition', + 'DATE' => 'biblio_date', + 'TYPE_OF_WORK' => 'biblio_type_of_work', + 'SHORT_TITLE' => 'biblio_short_title', + 'ALTERNATE_TITLE' => 'biblio_alternate_title', + 'ISBN' => 'biblio_isbn', + 'ORIGINAL_PUB' => 'biblio_original_publication', + 'REPRINT_EDITION' => 'biblio_reprint_edition', + 'REVIEWED_ITEM' => '', + 'CUSTOM1' => 'biblio_custom1', + 'CUSTOM2' => 'biblio_custom2', + 'CUSTOM3' => 'biblio_custom3', + 'CUSTOM4' => 'biblio_custom4', + 'CUSTOM5' => 'biblio_custom5', + 'CUSTOM6' => 'biblio_custom6', + 'ACCESSION_NUMBER' => 'biblio_accession_number', + 'CALL_NUMBER' => 'biblio_call_number', + 'LABEL' => 'biblio_label', + 'KEYWORD' => 'biblio_keywords', + 'ABSTRACT' => 'biblio_abst_e', + 'NOTES' => 'biblio_notes', + 'URL' => 'biblio_url', + 'AUTHOR_ADDRESS' => '', + 'IMAGE' => '', + 'CAPTION' => '', + ) + ); + + $map['format'] = 'endnote7'; + return $map; +} +/** + * Implementation of hook_schema(). + * + * Note: Pro Drupal Development models use of t() to translate 'description' + * for field definitions, but Drupal core does not use them. We follow core. + */ +function biblio_xml_schema() { + $schema = array(); + $schema['biblio_xml'] = array( + 'fields' => array( + 'nid' => array('type' => 'int', 'not null' => TRUE), + 'biblio_xml_md5' => array('type' => 'char', 'length' => 32, 'not null' => TRUE), + ), + 'primary key' => array('nid'), + ); + return $schema; +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/endnote/biblio_xml.module --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/endnote/biblio_xml.module Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,139 @@ + 2, + 'path' => drupal_get_path('module', 'biblio_xml') . '/views', + ); +} + + /* + * add the xml 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_xml', 'biblio_import',...) + */ +function biblio_xml_biblio_import_options() { + return array('biblio_xml' => t('EndNote XML')); +} +function biblio_xml_biblio_mapper_options() { + return array( + 'endnote7' => array( + 'title' => t('EndNote 7 XML'), + 'export' => TRUE, + ), + 'endnote8' => array( + 'title' => t('EndNote X3 XML'), + 'export' => TRUE, + ), + ); +} + +function biblio_xml_biblio_export_options() { + return array('xml' => t('EndNote XML')); +} + +function biblio_xml_node_view($node, $view_mode) { + if ($node->type == 'biblio') { + switch ($view_mode) { + case 'full': + case 'teaser': + $links = biblio_xml_biblio_export_link($node->nid); + $node->content['links']['biblio_xml'] = array( + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); + } + } +} + +/** + * Creates a link to export a node (or view) in xml 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 (xml) + */ +function biblio_xml_biblio_export_link($nid = NULL, $filter = array()) { + $show_link = variable_get('biblio_export_links', array('xml' => TRUE)); + if (!isset($show_link['xml']) || empty($show_link['xml']) || !biblio_access('export')) { + return array(); + } + $base = variable_get('biblio_base', 'biblio'); + + $link = array(); + $link['attributes']['title'] = t("Click to download the EndNote XML formatted file"); + $link['attributes'] += array('rel' => 'nofollow'); + + $link['href'] = "$base/export/xml"; + if (!empty($nid)) { + $link['href'] .= '/' . $nid; + } + $link['title'] = t('XML'); + + if (empty($nid) && !empty($filter)) { // add any filters which may be on the current page + $link['query'] = $filter; + } + return array('biblio_xml' => $link); +} + +function biblio_xml_node_delete($node) { + if ($node->type != 'biblio') { + return; + } + db_delete('biblio_xml') + ->condition('nid', $node->nid) + ->execute(); +} + +function biblio_xml_node_insert($node) { + if ($node->type != 'biblio' || !isset($node->biblio_xml_md5)) { + return; + } + drupal_write_record('biblio_xml', $node); +} + +function biblio_xml_biblio_import($file, $terms = array(), $batch = FALSE, $session_id = NULL, $save = TRUE, $string = FALSE) { + module_load_include('inc', 'biblio_xml', 'endnote_xml_parser'); + + $nids = array(); + $dups = array(); + + $parser = new EndNoteXMLParser; + + list($nids, $dups) = $parser->parse($file, $terms, $batch, $session_id); + + return array($nids, $dups); +} + +function biblio_xml_biblio_export($nids) { + module_load_include('inc', 'biblio_xml', 'endnote8_export'); + drupal_add_http_header('Content-type', 'application/xml; charset=utf-8'); + drupal_add_http_header('Content-Disposition', 'attachment; filename="Biblio-EndNote.xml"'); + + print _endnote8_XML_export('', 'begin'); + $nodes = node_load_multiple($nids, array(), TRUE); + foreach ($nodes as $node) { + // $node = node_load($nid, FALSE, TRUE); + if (variable_get('biblio_hide_bibtex_braces', 0) ) { + $node->title = biblio_remove_brace($node->title); + } + print _endnote8_XML_export($node); + } + + print _endnote8_XML_export('', 'end'); +} + +function biblio_xml_endnote8_map_reset($type = NULL) { + module_load_include('install', 'biblio_xml', 'biblio_xml'); + _reset_endnote_xml_map('endnote8', $type); +} + +function biblio_xml_endnote7_map_reset($type = NULL) { + module_load_include('install', 'biblio_xml', 'biblio_xml'); + _reset_endnote_xml_map('endnote7', $type); +} + + diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/endnote/endnote8_export.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/endnote/endnote8_export.inc Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,201 @@ +'; + $xml .= "
' . $popup_data . ''; +} + +function _biblio_marc_export($node) { + module_load_include('php', 'biblio_marc', 'php-marc'); + $record = new Record(); + // case '008': + // $data = $field->data(); + // $node->biblio_year = substr($data, 7, 4); + // $node->biblio_lang = substr($data, 35, 3); + // break; + $leader = $record->leader(); + if ($node->biblio_type == 100) { + $type = 'nam a'; + } + else { + $type = 'nas a'; + } + $record->leader(substr_replace($leader, $type, 5, 5)); + + $rec_eight = str_repeat(' ', 40); + $rec_eight = substr_replace($rec_eight, $node->biblio_year, 7, 4); + $rec_eight = substr_replace($rec_eight, $node->biblio_lang, 35, 3); + $rec_eight = substr_replace($rec_eight, 'd', 39, 1); + $field = new Field("008", $rec_eight); + $record->append_fields($field); + + if (!empty($node->biblio_isbn)) { + $field = new Field("020", "", "", array("a" => $node->biblio_isbn)); + $record->append_fields($field); + } + if (!empty($node->biblio_issn)) { + $field = new Field("022", "", "", array("a" => $node->biblio_issn)); + $record->append_fields($field); + } + if (!empty($node->biblio_other_number)) { + $field = new Field("024", "", "", array("a" => $node->biblio_other_number)); + $record->append_fields($field); + } + if (!empty($node->biblio_call_number)) { + $field = new Field("050", "", "", array("a" => $node->biblio_call_number)); + $record->append_fields($field); + } + if (!empty($node->title)) { + $field = new Field("245", "0", "0", array("a" => $node->title)); + $record->append_fields($field); + } + if (!empty($node->biblio_sort_title)) { + $field = new Field("210", "0", "#", array("a" => $node->biblio_sort_title)); + $record->append_fields($field); + } + // case '245': + // $node->title = str_replace(' /', '', $field->subfield('a')) . ' ' . $field->subfield('b'); + // break; + if (!empty($node->biblio_edition)) { + $field = new Field("250", "", "", array("a" => $node->biblio_edition)); + $record->append_fields($field); + } + if (!empty($node->biblio_place_published)) { + $subfields['a'] = $node->biblio_place_published; + } + if (!empty($node->biblio_publisher)) { + $subfields['b'] = $node->biblio_publisher; + } + if (!empty($node->biblio_date)) { + $subfields['c'] = $node->biblio_date; + } + if (!empty($subfields)) { + $field = new Field("260", "", "", $subfields); + $record->append_fields($field); + } + if (!empty($node->biblio_pages)) { + $field = new Field("300", "", "", array("a" => $node->biblio_pages)); + $record->append_fields($field); + } + if (!empty($node->biblio_volume)) { + $field = new Field("490", "0", "", array("v" => $node->biblio_volume)); + $record->append_fields($field); + } + if (!empty($node->biblio_abst_e)) { + $field = new Field("520", "3", "#", array("a" => $node->biblio_abst_e)); + $record->append_fields($field); + } + // case ($tagnum >= 500 && $tagnum <= 599): + // $value = $field->subfield('a'); + // if (!empty($value)) { + // $node->biblio_notes .= $value; + // } + if (!empty($node->biblio_keywords)) { + foreach($node->biblio_keywords as $keyword) { + $field = new Field("653", "1", "0", array("a" => $keyword)); + $record->append_fields($field); + } + } + if (!empty($node->biblio_contributors)) { + foreach ($node->biblio_contributors as $i => $author) { + $first = $author['firstname']; + $last = $author['lastname']; + $init = $author['initials']; + $cat = $author['auth_category']; + $name = $last . ($first ? ', ' . $first : '') . ($init ? ', ' . $init : ''); + $tag = ($i == 0 ? ($cat == 5 ? 110 :100) : ($cat == 5 ? 710 :700)); + $field = new Field($tag, "1", "#", array("a" => $name)); + $record->append_fields($field); + } + } + if (!empty($node->biblio_url)) { + $url = $node->biblio_url; + } + else { + $options['absolute'] = TRUE; + $url = url("node/$node->nid", $options); + } + if (!empty($url)) { + $field = new Field("856", "", "", array("u" => $url)); + $record->append_fields($field); + } + return $record->raw(); + +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/marcParse/example.mrc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/marcParse/example.mrc Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,1 @@ +01850 2200517 45000010011000000030007000110080039000180200026000570350015000830400007000980420012001050840018001170840018001350840021001530840022001741000030001962450062002262500013002882600058003013000033003594400037003925000023004295990010004527400024004627750034004868410048005208410049005688410047006178410048006648410047007128410047007598520038008068520021008448520013008658520016008788520028008948520021009229000056009439000060009999000057010599000056011169000057011729000060012299760026012890050017013150000000044EMILDA980120s1998 fi j 000 0 swe a9515008808cFIM 72:00 99515008808 aNB 9NB9SEE aHcd,u2kssb/6 5NBauHc2kssb 5SEEaHcf2kssb/6 5QaHcd,uf2kssb/61 aJansson, Tove,d1914-200104aDet osynliga barnet och andra berttelser /cTove Jansson a7. uppl. aHelsingfors :bSchildt,c1998 ;e(Falun :fScandbook) a166, [4] s. :bill. ;c21 cm 0aMumin-biblioteket,x99-0698931-9 aOriginaluppl. 1962 aLi: S4 aDet osynliga barnet1 z951-50-0385-7w9515003857907 5Liaxab0201080u 0 4000uu |000000e1 5SEEaxab0201080u 0 4000uu |000000e1 5Laxab0201080u 0 4000uu |000000e1 5NBaxab0201080u 0 4000uu |000000e1 5Qaxab0201080u 0 4000uu |000000e1 5Saxab0201080u 0 4000uu |000000e1 5NBbNBcNB98:12hpliktjR, 980520 5LibLicCNBhh,u 5SEEbSEE 5QbQj98947 5LbLc0100h98/j3043 H 5SbShSv97j72351saYanson, Tobe,d1914-2001uJansson, Tove,d1914-20011saJanssonov, Tove,d1914-2001uJansson, Tove,d1914-20011saJansone, Tuve,d1914-2001uJansson, Tove,d1914-20011saJanson, Tuve,d1914-2001uJansson, Tove,d1914-20011saJansson, Tuve,d1914-2001uJansson, Tove,d1914-20011saJanssonova, Tove,d1914-2001uJansson, Tove,d1914-2001 2aHcd,ubSknlitteratur20050204111518.0 \ No newline at end of file diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/marcParse/example.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/marcParse/example.php Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,85 @@ + +// +//----------------------------------------------------------------------------- +// +// 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$ +// +//----------------------------------------------------------------------------- + +require_once "../php-marc/php-marc.php"; + +// Other way to access file +/*$string = file("example.mrc"); +$file = new USMARC($string[0]);*/ + +// Open file +$file = new File("example.mrc"); + +// Read next record +$record = $file->next(); + +// Create new field +$field = new Field("245", "", "", array("a" => "Mumin")); +// Add subfield +$field->add_subfields(array("b" => "Det Osynliga Barnet")); +// Other ways to update field +$field->update(array("ind2" => "1", "b" => "Vinter i Mumindalen", "c" => "Tove Jansson")); + +// Replace existing field +$existing =& $record->field("245"); +$existing->replace_with($field); + +$clone = $field->make_clone(); +// Change some more +$clone->update(array("a" => "Muminsagor", "b" => "Muminpappans memoarer")); + +// And append to record +$record->append_fields($clone); + +// Some output +print "
"; +print $record->formatted(); +print "\n\n"; +print $file->raw[0]; +print "\n"; +print $record->raw(); +print "\n\n"; +print $record->ffield("245", "Formatted output: Title: %a, Remainder of title: %b, Responsibility: %c\n"); +print ""; + +?> \ No newline at end of file diff -r d72257b2ddc2 -r a75ead649730 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:18:21 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; $i
"; + $attrs = $text->attributes(); + if (isset($attrs['Label'])) { + $abst .= '' . $attrs['Label'] . ': '; + } + $abst .= (string)$text . '
'; + } + return $abst; + } + } +} diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/pubmed/biblio_pm.admin.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/pubmed/biblio_pm.admin.inc Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,101 @@ + 'fieldset', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#group' => 'biblio_settings', + '#title' => t('PubMed'), + '#description' => t('Please select the action to be performed by the PubMed module when it detects changes to an existing entry.'), + '#weight' => 105, + ); + $form['pm_options']['biblio_pm_dup_action'] = array( + '#type' => 'radios', + '#title' => t('Actions'), + '#default_value' => variable_get('biblio_pm_dup_action', 'newrev'), + '#options' => array( + 'newrev' => t('Accept and create a new revision of the existing node.'), + 'replace' => t('Accept and replace the existing node.'), + 'reject' => t('Reject and keep the existing node.'), + ) + ); + $form['pm_options']['biblio_pm_auto_update'] = array( + '#type' => 'checkbox', + '#title' => t('Automatically check for updates via CRON'), + '#return_value' => 1, + '#default_value' => variable_get('biblio_pm_auto_update', 0), + '#description' => t('Entries which were orginally downloaded from PubMed will be periodically checked and updated if the source record has changed.') + ); + $form['pm_options']['pm_cron'] = array( + '#type' => 'fieldset', + '#collapsible' => FALSE, + '#collapsed' => FALSE, +// '#group' => 'pm_options', + '#title' => t('CRON Settings'), + ); + $form['pm_options']['pm_cron']['biblio_pm_update_interval'] = array( + '#type' => 'select', + '#title' => t('PubMed update frequency'), + '#default_value' => variable_get('biblio_pm_update_interval', 3600), + '#options' => array( + 0 => t('Every CRON run'), + 3600 => t('Hourly'), + 86400 => t('Daily'), + 604800 => t('Weeekly'), + ), + '#description' => t('How frequently should we check for updates.'), + '#states' => array( + 'invisible' => array( + 'input[name="biblio_pm_auto_update"]' => array('checked' => FALSE), + ), + ), + ); + $form['pm_options']['pm_cron']['biblio_pm_update_limit'] = array( + '#type' => 'select', + '#title' => t('Number of items to check per CRON run'), + '#default_value' => variable_get('biblio_pm_update_limit', 100), + '#options' => array( + 10 => 10, + 20 => 20, + 50 => 50, + 100 => 100, + 500 => 500, + ), + '#description' => t('The maximum number of items updated in each pass of a cron maintenance task. If necessary, reduce the number of items to prevent timeouts and memory errors while updating.'), + '#states' => array( + 'invisible' => array( + 'input[name="biblio_pm_auto_update"]' => array('checked' => FALSE), + ), + ), + ); + $form['pm_options']['pm_cron']['biblio_pm_age_limit'] = array( + '#type' => 'select', + '#title' => t('Length of time to wait before re-checking for updates'), + '#default_value' => variable_get('biblio_pm_age_limit', 2419200), + '#options' => array( + 86400 => t('1 Day'), + 604800 => t('1 Week'), + 2419200 => t('1 Month'), + 29030400 => t('1 Year'), + ), + '#description' => t('Wait this long before checking for updates on a given node again.'), + '#states' => array( + 'invisible' => array( + 'input[name="biblio_pm_auto_update"]' => array('checked' => FALSE), + ), + ), + ); + + + return ($form); +} \ No newline at end of file diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/pubmed/biblio_pm.info --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/pubmed/biblio_pm.info Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,14 @@ +name = Biblio - PubMed +description = Provides PubMed import and search to the Biblio module. +core = 7.x +package = Biblio +dependencies[] = biblio +files[] = EntrezClient.php +files[] = EntrezPubmedArticle.php + +; 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 d72257b2ddc2 -r a75ead649730 modules/biblio/modules/pubmed/biblio_pm.install --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/pubmed/biblio_pm.install Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,158 @@ +fields(array('weight' => 19)) + ->condition('name', 'biblio_pm') + ->execute(); +} + +/** + * Implementation of hook_schema(). + * + * Note: Pro Drupal Development models use of t() to translate 'description' + * for field definitions, but Drupal core does not use them. We follow core. + */ +function biblio_pm_schema() { + $schema = array(); + $schema['biblio_pubmed'] = array( + 'fields' => array( + 'biblio_pubmed_id' => array( + 'type' => 'int', + 'not null' => TRUE + ), + 'biblio_pmcid' => array( + 'type' => 'varchar', + 'length' => 20, + ), + 'nid' => array( + 'type' => 'int', + 'not null' => TRUE + ), + 'biblio_pubmed_md5' => array( + 'type' => 'char', + 'length' => 32, + 'not null' => TRUE + ), + 'biblio_pm_changed' => array( + 'description' => 'The Unix timestamp when the pmid was most recently saved.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0 + ), + ), + 'primary key' => array('nid'), + ); + + $schema['biblio_pubmed_grant_info'] = array( + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'unsigned' => TRUE, + ), + 'nid' => array( + 'type' => 'int', + 'not null' => TRUE + ), + 'biblio_pubmed_id' => array( + 'type' => 'int', + 'not null' => TRUE + ), + 'grantid' => array( + 'type' => 'varchar', + 'length' => 255, + ), + 'acronym' => array( + 'type' => 'varchar', + 'length' => 2, + ), + 'agency' => array( + 'type' => 'varchar', + 'length' => 255, + ), + 'country' => array( + 'type' => 'varchar', + 'length' => 255, + ), + ), + 'primary key' => array('id'), + ); + return $schema; +} + + +/** +* +* UPDATES +* +*/ + + +/** +* +* add two new fields to the biblio_pubmed table +* +*/ + +function biblio_pm_update_7001() { + $spec = array( + 'description' => 'The Unix timestamp when the pmid was most recently saved.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0 + ); + db_add_field('biblio_pubmed', 'biblio_pm_changed', $spec); + $spec = array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ); + db_add_field('biblio_pubmed', 'biblio_pmcid', $spec); +} +/** +* +* change field type for biblio_pmcid field to the biblio_pubmed table +* +*/ + +function biblio_pm_update_7002() { + $spec = array( + 'type' => 'varchar', + 'length' => 20, + 'not null' => FALSE, + ); + db_change_field('biblio_pubmed', 'biblio_pmcid', 'biblio_pmcid', $spec); +} +/** + * Add a new table 'biblio_pubmed_grant_info' + */ +function biblio_pm_update_7004() { + $schema = biblio_pm_schema(); + $spec = $schema['biblio_pubmed_grant_info']; + db_create_table('biblio_pubmed_grant_info', $spec); +} \ No newline at end of file diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/modules/pubmed/biblio_pm.module --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/biblio/modules/pubmed/biblio_pm.module Fri Sep 20 11:18:21 2013 +0100 @@ -0,0 +1,525 @@ += variable_get('biblio_pm_update_next_execution', 0)) { + $ids = array(); + $result = db_select('biblio_pubmed', 'bpm') + ->fields('bpm', array('nid', 'biblio_pubmed_id')) + ->condition('biblio_pm_changed', $age_limit, '<') + ->orderBy('nid', 'ASC') + ->range(0, $count_limit) + ->execute(); + foreach ($result as $pm) { + $ids[$pm->nid] = $pm->biblio_pubmed_id; + } + if (count($ids)) { + + list($nids, $dups) = biblio_pm_import_ids($ids); + + if (count($nids)) { + foreach ($nids as $nid) { + $message = ''; + $message = t('!nid was updated due to changes originating at !url', array( + '!nid' => l($nid, 'node/' . $nid), + '!url' => l(t('PubMed'), 'http://www.ncbi.nlm.nih.gov/pubmed/' . $ids[$nid]), + ) + ); + watchdog('biblio_pm', $message, array(), WATCHDOG_WARNING); + } + } + + if (count($dups)) { + $count = count($dups); + $message = format_plural($count, 'One duplicate PubMed entry was checked, but no changes were found.', + '@count PubMed entries were checked, but no changes were found.'); + watchdog('biblio_pm', $message, array('@count' => $count), WATCHDOG_INFO); + + $now = time(); + + db_update('biblio_pubmed') + ->fields(array('biblio_pm_changed' => $now)) + ->condition('nid', $dups, 'IN') + ->execute(); + } + } + else { + $message = t('There were no PubMed entries older than @age to check.', array( + '@age' => format_interval($age)) + ); + } + watchdog('biblio_pm', $message, array(), WATCHDOG_INFO); + variable_set('biblio_pm_update_next_execution', time() + $interval); + } + } +} + +function biblio_pm_form_biblio_admin_settings_alter(&$form, &$form_state) { + module_load_include('inc', 'biblio_pm', 'biblio_pm.admin'); + $form += biblio_pm_settings_form(); +} + +function biblio_pm_form_biblio_node_form_alter(&$form, &$form_state, $form_id) { + + if (($form_id == 'biblio_node_form') && isset($form_state['biblio_fields'])) { + + if (isset($form_state['values']['biblio_pubmed_id'])) { + $default_pubmed_id = $form_state['values']['biblio_pubmed_id']; + } + elseif (isset($form_state['node']->biblio_pubmed_id)) { + $default_pubmed_id = $form_state['node']->biblio_pubmed_id ; + } + else { + $default_pubmed_id = ''; + } + + if (isset($form_state['values']['biblio_pmcid'])) { + $default_pmcid = $form_state['values']['biblio_pmcid']; + } + elseif (isset($form_state['node']->biblio_pmcid)) { + $default_pmcid = $form_state['node']->biblio_pmcid ; + } + else { + $default_pmcid = ''; + } + + $form['biblio_tabs'][4]['biblio_pubmed_id'] = array( + '#type' => 'textfield', + '#title' => t('PMID'), + '#required' => FALSE, + '#description' => t('PubMed ID'), + '#default_value' => $default_pubmed_id, + '#size' => 50, + '#maxlength' => 50, + ); + + + $form['biblio_tabs'][4]['biblio_pmcid'] = array( + '#type' => 'textfield', + '#title' => t('PMCID'), + '#required' => FALSE, + '#description' => t('PubMed Central ID'), + '#default_value' => $default_pmcid, + '#size' => 50, + '#maxlength' => 50, + ); + + } + if ((!isset($form_state['biblio_type']) || empty($form_state['biblio_type'])) && !isset($form_state['node']->nid)) { + $form['biblio_pubmed_lookup'] = array( + '#type' => 'fieldset', + '#title' => t('PubMed Lookup'), + '#weight' => -20, + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $form['biblio_pubmed_lookup']['PMID'] = array( + '#type' => 'textfield', + '#title' => t('PubMed ID'), + '#required' => FALSE, + '#default_value' => '', + '#description' => t('Enter a PubMed ID'), + '#size' => 60, + '#maxlength' => 255, + '#weight' => -4 + ); + $form['biblio_pubmed_lookup']['pubmed_submit'] = array( + '#type' => 'submit', + '#value' => t('Populate using PubMed'), + '#submit' => array('biblio_pm_form_biblio_node_form_submit') + ); + // $form['#submit'] = array_merge(array('biblio_pm_form_biblio_node_form_submit'), isset($form['#submit'])?$form['#submit']:array()); // put my validator first + } + if (isset($form_state['values']['biblio_pubmed_id'])) { + $form['biblio_pubmed_id'] = array('#type' => 'value', '#value' => $form_state['values']['biblio_pubmed_id']); + } + if (isset($form_state['values']['biblio_pubmed_md5'])) { + $form['biblio_pubmed_md5'] = array('#type' => 'value', '#value' => $form_state['values']['biblio_pubmed_md5']); + } + if (isset($form_state['values']['biblio_pmcid'])) { + $form['biblio_pmcid'] = array('#type' => 'value', '#value' => $form_state['values']['biblio_pmcid']); + } + if (isset($form_state['values']['biblio_pubmed_grants'])) { + $form['biblio_pubmed_grants'] = array('#type' => 'value', '#value' => $form_state['values']['biblio_pubmed_grants']); + } + +} + +function biblio_pm_form_biblio_node_form_submit($form, &$form_state) { + $node_data = array(); + if (strlen($pmid = $form_state['values']['PMID'])) { + if (!($dup = biblio_pm_check_pmid($pmid))) { + module_load_include('php', 'biblio_pm', 'EntrezClient'); + module_load_include('php', 'biblio_pm', 'EntrezPubmedArticle'); + $Eclient = new BiblioEntrezClient; + try { + $result = $Eclient->fetch($pmid); + } catch (Exception $e) { + form_set_error($e->getMessage()); + } + if (!isset($result->PubmedArticle)) { + unset($form_state['values']['biblio_type']); + unset($form_state['post']['biblio_type']); + form_set_error('PMID', 'No data available for PubMed ID: ' . check_plain($pmid)); + return; + } + $data = new BiblioEntrezPubmedArticle($result->PubmedArticle); + $node_data = $data->getBiblio(); + } + else { + $message = t('The PubMed ID that you are trying to import already exists in the database, see !url', array('!url' => l('node/' . $dup, 'node/' . $dup))); + form_set_error('PMID', $message); + $form_state['rebuild'] = TRUE; + $form_state['submitted'] = FALSE; + unset($form_state['values']['biblio_type']); + } + } + if (!empty($node_data)) { + $form_state['values'] = array_merge($form_state['values'], $node_data); + $form_state['input']['biblio_type'] = $form_state['biblio_type'] = $node_data['biblio_type']; + $form_state['input']['biblio_pmcid'] = $form_state['biblio_pmcid'] = isset($node_data['biblio_pmcid']) ? $node_data['biblio_pmcid'] : ''; + $form_state['input']['biblio_pubmed_id'] = $form_state['biblio_pubmed_id'] = $node_data['biblio_pubmed_id']; + $form_state['input']['biblio_pubmed_grants'] = $form_state['biblio_pubmed_grants'] = isset($node_data['biblio_pmcid']) ? $node_data['biblio_pmcid'] : array(); + $form_state['rebuild'] = TRUE; + } + + return; +} + +function biblio_pm_biblio_import_options() { + return array( + 'biblio_pm' => t('PubMed ID List'), + 'biblio_pm_xml' => t('PubMed XML') + ); +} + +function biblio_pm_biblio_import($file, $terms = array(), $batch = FALSE, $session_id = NULL, $save = TRUE, $string = FALSE) { + $nids = array(); + $dups = array(); + $pmids = file($file->uri, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (empty($pmids)) { + drupal_set_message(t("Could not open PubMed ID file"), 'error'); + return; + } + return biblio_pm_import_ids($pmids, $terms, $batch, $session_id); +} + +/** + * Imports article(s) from an XML file (exported) from PubMed Central + * + * @param file object $file + * @param array $terms + * @param bool $batch + * @param string $session_id + * @return array + */ +function biblio_pm_xml_biblio_import($file, $terms = array(), $batch = FALSE, $session_id = NULL) { + libxml_use_internal_errors(true); + $xml = @simplexml_load_file($file->uri); + if (empty($xml) || isset($xml->body->pre->ERROR)) { + drupal_set_message(t("Could not parse file as PubMed XML"), 'error'); + return; + } + return _biblio_pm_create_node_from_xml($xml, $terms, $batch, $session_id); +} + +/** + * Imports multiple PMIDs + * + * @param array $pmids + * @param array $terms + * @param bool $batch + * @param string $session_id + * @return array: + */ +function biblio_pm_import_ids($pmids, $terms = array(), $batch = FALSE, $session_id = NULL) { + module_load_include('php', 'biblio_pm', 'EntrezClient'); + $retmax = 100; + $resmax = count($pmids); + $start = 0; + $Eclient = new BiblioEntrezClient; + $Eclient->post($pmids); + $Eclient->setReturnMax($retmax); + $nids = array(); + $dups = array(); + while ($start < $resmax && ($result = $Eclient->fetchRecords($start))) { + $start += count($result->xpath('//PubmedArticle')); + list($nid, $dup) = _biblio_pm_create_node_from_xml($result, $terms, $batch, $session_id); + $nids = array_merge($nids, $nid); + $dups = array_merge($dups, $dup); + } + + return array($nids, $dups); +} + +/** + * Fetches the article for the given PMID and returns a biblio node object + * + * Returns an empty node object if the PMID is not found. + * + * @param int $pmid + * @return stdClass $node + */ +function biblio_pm_fetch_pmid($pmid) { + $node = new stdClass; + $Eclient = new BiblioEntrezClient; + $paser = new BiblioEntrezPubmedArticle(); + try { + $xml = $Eclient->fetch($pmid); + } + catch (Exception $e) { + return $node; + } + $articles = $xml->xpath('//PubmedArticle'); + if (count($articles)) { + $node = $paser->setArticle($articles[0])->getBiblioAsObject(); + if (!empty($node)) { + $node->type = 'biblio'; + node_object_prepare($node); + } + } + return $node; +} + +function _biblio_pm_create_node_from_xml($xml, $terms, $batch, $session_id) { + module_load_include('php', 'biblio_pm', 'EntrezPubmedArticle'); + $nids = array(); + $dups = array(); + $node = new stdClass(); + $data = new BiblioEntrezPubmedArticle(); + + foreach ($xml->xpath('//PubmedArticle') as $article) { + $node = $data->setArticle($article)->getBiblioAsObject(); + if (isset($node)) { + $dup = biblio_pm_check_md5($node->biblio_pubmed_id, $node->biblio_pubmed_md5); + $action = variable_get('biblio_pm_dup_action', 'newrev'); + if ($dup < 0 && $action == 'newrev') { //entry has be imported before, but may have changed + // Load the node in order to preserve all its data and merge the new + // data from pubmed. + $node = (object) array_merge((array)node_load(-$dup), (array)$node); + $node->nid = -$dup; + $node->revision = 1; + $curr_date = format_date(time()); + $node->log = t('Automatically updated by the Biblio PubMed module on !date due to changes at !url', array( + '!date' => $curr_date, + '!url' => l('PubMed', 'http://www.ncbi.nlm.nih.gov/pubmed/' . $node->biblio_pubmed_id), + )); + $dup = NULL; + } + if ($dup < 0 && $action == 'replace') { //entry has be imported before, but may have changed + $node->nid = -$dup; + $existing_node = db_query("SELECT * FROM {node} WHERE nid=:nid", array(':nid' => $node->nid))->fetchObject(); + $node = (object) array_merge((array)$existing_node, (array)$node); + $dup = NULL; + } + if (!$dup) { + // Allows other modules to alter the node before it is being saved. (Note: $article is a SimpleXML object) + drupal_alter('biblio_pm_node', $node, $article); + biblio_save_node($node, $terms, $batch, $session_id); + if (!empty($node->nid)) $nids[] = $node->nid; + } + else { + $dups[] = $dup; + } + $node = NULL; + } + } + return array($nids, $dups); +} + +function biblio_pm_check_pmid($pmid) { + return db_query("SELECT nid FROM {biblio_pubmed} WHERE biblio_pubmed_id = :pmid", array(':pmid' => $pmid))->fetchField(); +} + +function biblio_pm_biblio_lookup_link_settings() { + return array('pubmed' => t('PubMed')); +} + +function biblio_pm_biblio_lookup_link($node) { + $show_link = variable_get('biblio_lookup_links', array('pubmed' => TRUE)); + if (!isset($show_link['pubmed']) || + !$show_link['pubmed'] || + !isset($node) || + $node->type != 'biblio' || + !isset($node->biblio_pubmed_id)) { + return array(); + } + + $link = 'http://www.ncbi.nlm.nih.gov/pubmed/' . $node->biblio_pubmed_id . '?dopt=Abstract'; + $attrs = array('title' => t("Click to view the PubMed listing for this node")); + if (variable_get('biblio_links_target_new_window', NULL)) { + $attrs = array_merge($attrs, array('target' => '_blank')); + } + return array('biblio_pubmed' => array( + 'title' => t('PubMed'), + 'href' => $link, + 'attributes' => $attrs, + )); +} + +function biblio_pm_node_view($node, $view_mode, $langcode) { + if ($node->type == 'biblio' && isset($node->biblio_pubmed_id)) { + switch ($view_mode) { + case 'full': + case 'teaser': + $node->content['links']['biblio_pubmed'] = array( + '#links' => biblio_pm_biblio_lookup_link($node), + '#attributes' => array('class' => array('links', 'inline')), + ); + } + } +} + +function biblio_pm_node_delete($node) { + if ($node->type != 'biblio') { + return; + } + db_delete('biblio_pubmed') + ->condition('nid', $node->nid) + ->execute(); + db_delete('biblio_pubmed_grant_info') + ->condition('nid', $node->nid) + ->execute(); +} + + +function biblio_pm_node_insert($node) { + if (isset($node->biblio_pubmed_id) && !empty($node->biblio_pubmed_id)) { + $node->biblio_pm_changed = time(); + drupal_write_record('biblio_pubmed', $node); + } + if (isset($node->biblio_pubmed_grants) && is_array($node->biblio_pubmed_grants)) { + foreach ($node->biblio_pubmed_grants as $grant) { + $info = array( + 'nid' => $node->nid, + 'biblio_pubmed_id' => $node->biblio_pubmed_id + ); + $info += $grant; + drupal_write_record('biblio_pubmed_grant_info', $info); + } + } +} + +function biblio_pm_node_update($node) { + if (isset($node->biblio_pubmed_id) && !empty($node->biblio_pubmed_id)) { + $node->biblio_pm_changed = time(); + drupal_write_record('biblio_pubmed', $node, 'nid'); + } + if (isset($node->biblio_pubmed_grants) && is_array($node->biblio_pubmed_grants) && !empty($node->biblio_pubmed_grants)) { + db_delete('biblio_pubmed_grant_info') + ->condition('nid', $node->nid) + ->execute(); + foreach ($node->biblio_pubmed_grants as $grant) { + $info = array( + 'nid' => $node->nid, + 'biblio_pubmed_id' => $node->biblio_pubmed_id + ); + $info += $grant; + drupal_write_record('biblio_pubmed_grant_info', $info); + } + } +} + +function biblio_pm_node_load($nodes, $types) { + $result = db_select('biblio_pubmed', 'bpm') + ->fields('bpm', array('nid', 'biblio_pubmed_id', 'biblio_pmcid', 'biblio_pubmed_md5')) + ->condition('nid', array_keys($nodes)) + ->execute(); + +// $result = db_query('SELECT biblio_pubmed_id FROM {biblio_pubmed} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes))); + foreach ($result as $record) { + $nodes[$record->nid]->biblio_pubmed_id = $record->biblio_pubmed_id; + $nodes[$record->nid]->biblio_pmcid = $record->biblio_pmcid; + $nodes[$record->nid]->biblio_pubmed_md5 = $record->biblio_pubmed_md5; + } + + $result = db_select('biblio_pubmed_grant_info', 'bpmgi') + ->fields('bpmgi') + ->condition('nid', array_keys($nodes)) + ->execute(); + + foreach ($result as $record) { + $nodes[$record->nid]->biblio_pubmed_grants[] = array( + 'grantid' => $record->grantid, + 'acronym' => $record->acronym, + 'agency' => $record->agency, + 'country' => $record->country); + } +} + +function biblio_pm_check_md5($pmid, $md5) { + static $pm_md5s = array(); + static $pm_nids = array(); + if (empty($pm_md5s)) { + $result = db_query("SELECT * FROM {biblio_pubmed} "); + foreach ($result as $row ) { + $pm_md5s[$row->biblio_pubmed_md5] = $row->nid; + $pm_nids[$row->biblio_pubmed_id] = $row->nid; + } + } + if (isset($pm_nids[$pmid]) && isset($pm_md5s[$md5])) { // must be an exact duplicate of an existing node (return the nid) + return $pm_md5s[$md5]; + } + elseif (isset($pm_nids[$pmid]) && !isset($pm_md5s[$md5])) { //pmid has been save previously but content must have changed (return negative nid) + return -$pm_nids[$pmid]; + } + else { + $pm_md5s[$md5] = TRUE; // gaurd against duplicates in the same import + $pm_nids[$pmid] = TRUE; + return; + } +} + +function biblio_pm_views_api() { + return array('api' => 2); +} + +function biblio_pm_biblio_node_table_rows_alter(&$rows, $node) { + if (isset($node->biblio_pubmed_id) && !empty($node->biblio_pubmed_id)) { + $rows[] = array( + array( + 'data' => t('PubMed ID'), + 'class' => array('biblio-row-title') + ), + array( + 'data' => l($node->biblio_pubmed_id, 'http://www.ncbi.nlm.nih.gov/pubmed/' . $node->biblio_pubmed_id . '?dopt=Abstract') + ) + ); + } + if (isset($node->biblio_pmcid) && !empty($node->biblio_pmcid)) { + $rows[] = array( + array( + 'data' => t('PubMed Central ID'), + 'class' => array('biblio-row-title') + ), + array( + 'data' => check_plain($node->biblio_pmcid) + ) + ); + } + if (isset($node->biblio_pubmed_grants) && is_array($node->biblio_pubmed_grants)) { + + foreach ($node->biblio_pubmed_grants as $grant) { + $list[] = check_plain(implode(' / ', $grant)); + } + $rows[] = array( + array( + 'data' => t('Grant List'), + 'class' => array('biblio-row-title') + ), + array( + 'data' => implode('(.*?)<\/p>/mi", "\\1\\par ", $doc_buffer);
+ $doc_buffer = preg_replace("/(.*?)<\/strong>/mi", "\\b \\1\\b0 ", $doc_buffer);
+ $doc_buffer = preg_replace("/(.*?)<\/em>/mi", "\\i \\1\\i0 ", $doc_buffer);
+ $doc_buffer = preg_replace("/(.*?)<\/i>/mi", "\\i \\1\\i0 ", $doc_buffer);
+ $doc_buffer = preg_replace("/(.*?)<\/u>/mi", "\\ul \\1\\ul0 ", $doc_buffer);
+ $doc_buffer = preg_replace("/ ' . t('The list of nodes that can be referenced can provided by a view (Views module) using the "References" display type.') . ' '. t("Important D6 migration note:") . '';
+ $description .= ' ' . t('Choose the view and display that select the nodes that can be referenced. ' . t('No eligible view was found.') .' ' . t('The list of users that can be referenced can provided by a view (Views module) using the "References" display type.') . ' '. t("Important D6 migration note:") . '';
+ $description .= ' ' . t('Choose the view and display that select the nodes that can be referenced. ' . t('No eligible view was found.') .' ' . $message . ' >(.*?)<\/strike>/mi", "\\strike \\1\\strike0 ", $doc_buffer);
+ $doc_buffer = preg_replace("/(.*?)<\/sub>/mi", "{\\sub \\1}", $doc_buffer);
+ $doc_buffer = preg_replace("/(.*?)<\/sup>/mi", "{\\super \\1}", $doc_buffer);
+
+ //$doc_buffer = preg_replace("/ ';
+ // $output .= ($node->biblio_issue) ? '('. check_plain($node->biblio_issue).')' :'';
+ $output .= ($node->biblio_pages) ? check_plain($node->biblio_pages) . '.' : '';
+ break; // generic
+ }
+ /* if ($node->biblio_date) $output .= ', '. check_plain($node->biblio_date);
+ if ($node->biblio_number) $output .= ', Number '. check_plain($node->biblio_number);
+
+ if ($node->biblio_place_published) $output .= ', '. check_plain($node->biblio_place_published);
+ */
+ return filter_xss($output, biblio_get_allowed_tags());
+}
+/**
+ *
+ */
+function _apa_format_author($author) {
+ $format = $author['prefix'] . ' ' . $author['lastname'];
+ $format .= !empty ($author['firstname']) ? ' ' . drupal_substr($author['firstname'], 0, 1) . '.' : '';
+ $format .= !empty ($author['initials']) ? $author['initials'] . '.' : '';
+ return $format;
+}
\ No newline at end of file
diff -r d72257b2ddc2 -r a75ead649730 modules/biblio/styles/biblio_style_chicago.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/biblio/styles/biblio_style_chicago.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,473 @@
+ and
+// Richard Karnesky (.*?)<\/H1>/mi", "\\pard\\qc\\fs40 \\1\\par\\pard\\fs{$this->font_size} ", $doc_buffer);
+ //$doc_buffer = preg_replace("/
(.*?)<\/H2>/mi", "\\pard\\qc\\fs32 \\1\\par\\pard\\fs{$this->font_size} ", $doc_buffer);
+
+ $doc_buffer = preg_replace("/
(.*?)<\/h1>/mi", "\\fs48\\b \\1\\b0\\fs{$this->font_size}\\par ", $doc_buffer);
+ $doc_buffer = preg_replace("/
(.*?)<\/h2>/mi", "\\fs36\\b \\1\\b0\\fs{$this->font_size}\\par ", $doc_buffer);
+ $doc_buffer = preg_replace("/
(.*?)<\/h3>/mi", "\\fs27\\b \\1\\b0\\fs{$this->font_size}\\par ", $doc_buffer);
+
+
+ $doc_buffer = preg_replace("/
/i", "\\brdrb\\brdrs\\brdrw30\\brsp20 \\pard\\par ", $doc_buffer);
+ $doc_buffer = str_replace("
", "\\par ", $doc_buffer);
+ $doc_buffer = str_replace("
", "\\par ", $doc_buffer);
+ $doc_buffer = str_replace("
' . t("The field is currently configured to use the 'Master' display of the view %view_name.", array('%view_name' => $view_settings['view_name']));
+ $description .= '
' . t("It is highly recommended that you:
- edit this view and create a new display using the 'References' display type,
- update the field settings to explicitly select the correct view and display.");
+ $description .= '
' . t("The field will work correctly until then, but submitting this form might inadvertently change the field settings.") . '
Only views with a display of type "References" are eligible.') . '
'),
+ );
+
+ $default = implode(', ', $view_settings['args']);
+ $form['view']['args'] = array(
+ '#type' => 'textfield',
+ '#title' => t('View arguments'),
+ '#default_value' => $default,
+ '#required' => FALSE,
+ '#description' => t('Provide a comma separated list of arguments to pass to the view.'),
+ );
+ }
+ else {
+ $form['view']['no_view_help'] = array(
+ '#markup' => '
', $summary);
+}
+
+/**
+ * Implements hook_field_formatter_prepare_view().
+ *
+ * Preload all nodes referenced by items using 'full entity' formatters.
+ */
+function node_reference_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
+ // Load the referenced nodes, except for the 'node_reference_nid' which does
+ // not need full objects.
+
+ // Collect ids to load.
+ $ids = array();
+ foreach ($displays as $id => $display) {
+ if ($display['type'] != 'node_reference_nid') {
+ foreach ($items[$id] as $delta => $item) {
+ if ($item['access']) {
+ $ids[$item['nid']] = $item['nid'];
+ }
+ }
+ }
+ }
+ $entities = node_load_multiple($ids);
+
+ // Add the loaded nodes to the items.
+ foreach ($displays as $id => $display) {
+ if ($display['type'] != 'node_reference_nid') {
+ foreach ($items[$id] as $delta => $item) {
+ if ($item['access']) {
+ $items[$id][$delta]['node'] = $entities[$item['nid']];
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Implements hook_field_formatter_view().
+ */
+function node_reference_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+ $settings = $display['settings'];
+ $result = array();
+
+ switch ($display['type']) {
+ case 'node_reference_default':
+ case 'node_reference_plain':
+ foreach ($items as $delta => $item) {
+ if ($item['access']) {
+ $node = $item['node'];
+ $label = entity_label('node', $node);
+ if ($display['type'] == 'node_reference_default') {
+ $uri = entity_uri('node', $node);
+ $result[$delta] = array(
+ '#type' => 'link',
+ '#title' => $label,
+ '#href' => $uri['path'],
+ '#options' => $uri['options'],
+ );
+ }
+ else {
+ $result[$delta] = array(
+ '#markup' => check_plain($label),
+ );
+ }
+ if (!$node->status) {
+ $result[$delta]['#prefix'] = '';
+ $result[$delta]['#suffix'] = '';
+ }
+ }
+ }
+ break;
+
+ case 'node_reference_node':
+ // To prevent infinite recursion caused by reference cycles, we store
+ // diplayed nodes in a recursion queue.
+ $recursion_queue = &drupal_static(__FUNCTION__, array());
+
+ // If no 'referencing entity' is set, we are starting a new 'reference
+ // thread' and need to reset the queue.
+ // @todo Bug: $entity->referencing_entity on nodes referenced in a different
+ // thread on the page. E.g: 1 references 1+2 / 2 references 1+2 / visit homepage.
+ // We'd need a more accurate way...
+ if (!isset($entity->referencing_entity)) {
+ $recursion_queue = array();
+ }
+
+ // The recursion queue only needs to track nodes.
+ if ($entity_type == 'node') {
+ list($id) = entity_extract_ids($entity_type, $entity);
+ $recursion_queue[$id] = $id;
+ }
+
+ // Check the recursion queue to determine which nodes should be fully
+ // displayed, and which nodes will only be displayed as a title.
+ $nodes_display = array();
+ foreach ($items as $delta => $item) {
+ if ($item['access'] && !isset($recursion_queue[$item['nid']])) {
+ $nodes_display[$item['nid']] = $item['node'];
+ }
+ }
+
+ // Load and build the fully displayed nodes.
+ if ($nodes_display) {
+ foreach ($nodes_display as $nid => $node) {
+ $nodes_display[$nid]->referencing_entity = $entity;
+ $nodes_display[$nid]->referencing_field = $field['field_name'];
+ }
+ $nodes_built = node_view_multiple($nodes_display, $settings['node_reference_view_mode']);
+ }
+
+ // Assemble the render array.
+ foreach ($items as $delta => $item) {
+ if ($item['access']) {
+ if (isset($nodes_display[$item['nid']])) {
+ $result[$delta] = $nodes_built['nodes'][$item['nid']];
+ }
+ else {
+ $node = $item['node'];
+ $label = entity_label('node', $node);
+ $uri = entity_uri('node', $node);
+ $result[$delta] = array(
+ '#type' => 'link',
+ '#title' => $label,
+ '#href' => $uri['path'],
+ '#options' => $uri['options'],
+ );
+ if (!$node->status) {
+ $result[$delta]['#prefix'] = '';
+ $result[$delta]['#suffix'] = '';
+ }
+ }
+ }
+ }
+ break;
+
+ case 'node_reference_nid':
+ foreach ($items as $delta => $item) {
+ if ($item['access']) {
+ $result[$delta] = array(
+ '#markup' => $item['nid'],
+ );
+ }
+ }
+ break;
+
+ case 'node_reference_path':
+ foreach ($items as $delta => $item) {
+ if ($item['access']) {
+ $uri = entity_uri('node', $item['node']);
+ $options = array(
+ 'absolute' => $settings['absolute'],
+ 'alias' => !$settings['alias'],
+ );
+
+ $options += $uri['options'];
+ $result[$delta] = array(
+ '#markup' => url($uri['path'], $options),
+ );
+ }
+ }
+ break;
+ }
+
+ return $result;
+}
+
+/**
+ * Implements hook_field_widget_info().
+ */
+function node_reference_field_widget_info() {
+ return array(
+ 'node_reference_autocomplete' => array(
+ 'label' => t('Autocomplete text field'),
+ 'description' => t('Display the list of referenceable nodes as a textfield with autocomplete behaviour.'),
+ 'field types' => array('node_reference'),
+ 'settings' => array(
+ 'autocomplete_match' => 'contains',
+ 'size' => 60,
+ 'autocomplete_path' => 'node_reference/autocomplete',
+ ),
+ ),
+ );
+}
+
+/**
+ * Implements hook_field_widget_info_alter().
+ */
+function node_reference_field_widget_info_alter(&$info) {
+ $info['options_select']['field types'][] = 'node_reference';
+ $info['options_buttons']['field types'][] = 'node_reference';
+}
+
+/**
+ * Implements hook_field_widget_settings_form().
+ */
+function node_reference_field_widget_settings_form($field, $instance) {
+ $widget = $instance['widget'];
+ $defaults = field_info_widget_settings($widget['type']);
+ $settings = array_merge($defaults, $widget['settings']);
+
+ $form = array();
+ if ($widget['type'] == 'node_reference_autocomplete') {
+ $form['autocomplete_match'] = array(
+ '#type' => 'select',
+ '#title' => t('Autocomplete matching'),
+ '#default_value' => $settings['autocomplete_match'],
+ '#options' => array(
+ 'starts_with' => t('Starts with'),
+ 'contains' => t('Contains'),
+ ),
+ '#description' => t('Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of nodes.'),
+ );
+ $form['size'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Size of textfield'),
+ '#default_value' => $settings['size'],
+ '#element_validate' => array('_element_validate_integer_positive'),
+ '#required' => TRUE,
+ );
+ }
+ return $form;
+}
+
+/**
+ * Implements hook_field_widget_form().
+ */
+function node_reference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+ switch ($instance['widget']['type']) {
+ case 'node_reference_autocomplete':
+ $element += array(
+ '#type' => 'textfield',
+ '#default_value' => isset($items[$delta]['nid']) ? $items[$delta]['nid'] : NULL,
+ '#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'],
+ '#size' => $instance['widget']['settings']['size'],
+ '#maxlength' => NULL,
+ '#element_validate' => array('node_reference_autocomplete_validate'),
+ '#value_callback' => 'node_reference_autocomplete_value',
+ );
+ break;
+ }
+
+ return array('nid' => $element);
+}
+
+/**
+ * Value callback for a node_reference autocomplete element.
+ *
+ * Replace the node nid with a node title.
+ */
+function node_reference_autocomplete_value($element, $input = FALSE, $form_state) {
+ if ($input === FALSE) {
+ // We're building the displayed 'default value': expand the raw nid into
+ // "node title [nid:n]".
+ $nid = $element['#default_value'];
+ if (!empty($nid)) {
+ $q = db_select('node', 'n');
+ $node_title_alias = $q->addField('n', 'title');
+ $q->addTag('node_access')
+ ->condition('n.nid', $nid)
+ ->range(0, 1);
+ $result = $q->execute();
+ // @todo If no result (node doesn't exist or no access).
+ $value = $result->fetchField();
+ $value .= ' [nid:' . $nid . ']';
+ return $value;
+ }
+ }
+}
+
+/**
+ * Validation callback for a node_reference autocomplete element.
+ */
+function node_reference_autocomplete_validate($element, &$form_state, $form) {
+ $field = field_widget_field($element, $form_state);
+ $instance = field_widget_instance($element, $form_state);
+
+ $value = $element['#value'];
+ $nid = NULL;
+
+ if (!empty($value)) {
+ // Check whether we have an explicit "[nid:n]" input.
+ preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $value, $matches);
+ if (!empty($matches)) {
+ // Explicit nid. Check that the 'title' part matches the actual title for
+ // the nid.
+ list(, $title, $nid) = $matches;
+ if (!empty($title)) {
+ $real_title = db_select('node', 'n')
+ ->fields('n', array('title'))
+ ->condition('n.nid', $nid)
+ ->execute()
+ ->fetchField();
+ if (trim($title) != trim($real_title)) {
+ form_error($element, t('%name: title mismatch. Please check your selection.', array('%name' => $instance['label'])));
+ }
+ }
+ }
+ else {
+ // No explicit nid (the submitted value was not populated by autocomplete
+ // selection). Get the nid of a referencable node from the entered title.
+ $options = array(
+ 'string' => $value,
+ 'match' => 'equals',
+ 'limit' => 1,
+ );
+ $references = node_reference_potential_references($field, $options);
+ if ($references) {
+ // @todo The best thing would be to present the user with an
+ // additional form, allowing the user to choose between valid
+ // candidates with the same title. ATM, we pick the first
+ // matching candidate...
+ $nid = key($references);
+ }
+ else {
+ form_error($element, t('%name: found no valid post with that title.', array('%name' => $instance['label'])));
+ }
+ }
+ }
+
+ // Set the element's value as the node id that was extracted from the entered
+ // input.
+ form_set_value($element, $nid, $form_state);
+}
+
+/**
+ * Implements hook_field_widget_error().
+ */
+function node_reference_field_widget_error($element, $error, $form, &$form_state) {
+ form_error($element['nid'], $error['message']);
+}
+
+/**
+ * Builds a list of referenceable nodes suitable for the '#option' FAPI property.
+ *
+ * Warning: the function does NOT take care of encoding or escaping the node
+ * titles. Proper massaging needs to be performed by the caller, according to
+ * the destination FAPI '#type' (radios / checkboxes / select).
+ *
+ * @param $field
+ * The field definition.
+ * @param $flat
+ * Whether optgroups are allowed.
+ *
+ * @return
+ * An array of referenceable node titles, keyed by node id. If the $flat
+ * parameter is TRUE, the list might be nested by optgroup first.
+ */
+function _node_reference_options($field, $flat = TRUE) {
+ $references = node_reference_potential_references($field);
+
+ $options = array();
+ foreach ($references as $key => $value) {
+ // The label, displayed in selects and checkboxes/radios, should have HTML
+ // entities unencoded. The widgets (core's options.module) take care of
+ // applying the relevant filters (strip_tags() or filter_xss()).
+ $label = html_entity_decode($value['rendered'], ENT_QUOTES);
+ if (empty($value['group']) || $flat) {
+ $options[$key] = $label;
+ }
+ else {
+ // The group name, displayed in selects, cannot contain tags, and should
+ // have HTML entities unencoded.
+ $group = html_entity_decode(strip_tags($value['group']), ENT_QUOTES);
+ $options[$group][$key] = $label;
+ }
+ }
+
+ return $options;
+}
+
+/**
+ * Retrieves an array of candidate referenceable nodes.
+ *
+ * This info is used in various places (allowed values, autocomplete
+ * results, input validation...). Some of them only need the nids,
+ * others nid + titles, others yet nid + titles + rendered row (for
+ * display in widgets).
+ *
+ * The array we return contains all the potentially needed information,
+ * and lets consumers use the parts they actually need.
+ *
+ * @param $field
+ * The field definition.
+ * @param $options
+ * An array of options to limit the scope of the returned list. The following
+ * key/value pairs are accepted:
+ * - string: string to filter titles on (used by autocomplete).
+ * - match: operator to match the above string against, can be any of:
+ * 'contains', 'equals', 'starts_with'. Defaults to 'contains'.
+ * - ids: array of specific node ids to lookup.
+ * - limit: maximum size of the the result set. Defaults to 0 (no limit).
+ *
+ * @return
+ * An array of valid nodes in the form:
+ * array(
+ * nid => array(
+ * 'title' => The node title,
+ * 'rendered' => The text to display in widgets (can be HTML)
+ * ),
+ * ...
+ * )
+ */
+function node_reference_potential_references($field, $options = array()) {
+ // Fill in default options.
+ $options += array(
+ 'string' => '',
+ 'match' => 'contains',
+ 'ids' => array(),
+ 'limit' => 0,
+ );
+
+ $results = &drupal_static(__FUNCTION__, array());
+
+ // Create unique id for static cache.
+ $cid = $field['field_name'] . ':' . $options['match'] . ':'
+ . ($options['string'] !== '' ? $options['string'] : implode('-', $options['ids']))
+ . ':' . $options['limit'];
+ if (!isset($results[$cid])) {
+ $references = FALSE;
+ if (module_exists('views') && !empty($field['settings']['view']['view_name'])) {
+ $references = _node_reference_potential_references_views($field, $options);
+ }
+
+ if ($references === FALSE) {
+ $references = _node_reference_potential_references_standard($field, $options);
+ }
+
+ // Store the results.
+ $results[$cid] = !empty($references) ? $references : array();
+ }
+
+ return $results[$cid];
+}
+
+/**
+ * Helper function for node_reference_potential_references().
+ *
+ * Case of Views-defined referenceable nodes.
+ */
+function _node_reference_potential_references_views($field, $options) {
+ $settings = $field['settings']['view'];
+ $options['title_field'] = 'title';
+ return references_potential_references_view('node', $settings['view_name'], $settings['display_name'], $settings['args'], $options);
+}
+
+/**
+ * Helper function for node_reference_potential_references().
+ *
+ * List of referenceable nodes defined by content types.
+ */
+function _node_reference_potential_references_standard($field, $options) {
+ // Avoid useless work
+ if (!count($field['settings']['referenceable_types'])) {
+ return array();
+ }
+
+ $query = db_select('node', 'n');
+ $node_nid_alias = $query->addField('n', 'nid');
+ $node_title_alias = $query->addField('n', 'title', 'node_title');
+ $node_type_alias = $query->addField('n', 'type', 'node_type');
+ $query->addTag('node_access')
+ ->addMetaData('id', ' _node_reference_potential_references_standard')
+ ->addMetaData('field', $field)
+ ->addMetaData('options', $options);
+
+ if (is_array($field['settings']['referenceable_types'])) {
+ $query->condition('n.type', $field['settings']['referenceable_types'], 'IN');
+ }
+
+ if ($options['string'] !== '') {
+ switch ($options['match']) {
+ case 'contains':
+ $query->condition('n.title', '%' . $options['string'] . '%', 'LIKE');
+ break;
+
+ case 'starts_with':
+ $query->condition('n.title', $options['string'] . '%', 'LIKE');
+ break;
+
+ case 'equals':
+ default: // no match type or incorrect match type: use "="
+ $query->condition('n.title', $options['string']);
+ break;
+ }
+ }
+
+ if ($options['ids']) {
+ $query->condition('n.nid', $options['ids'], 'IN');
+ }
+
+ if ($options['limit']) {
+ $query->range(0, $options['limit']);
+ }
+
+ $query
+ ->orderBy($node_title_alias)
+ ->orderBy($node_type_alias);
+
+ $result = $query->execute()->fetchAll();
+ $references = array();
+ foreach ($result as $node) {
+ $references[$node->nid] = array(
+ 'title' => $node->node_title,
+ 'rendered' => check_plain($node->node_title),
+ );
+ }
+ return $references;
+}
+
+/**
+ * Menu callback for the autocomplete results.
+ */
+function node_reference_autocomplete($entity_type, $bundle, $field_name, $string = '') {
+ $field = field_info_field($field_name);
+ $instance = field_info_instance($entity_type, $field_name, $bundle);
+
+ $options = array(
+ 'string' => $string,
+ 'match' => $instance['widget']['settings']['autocomplete_match'],
+ 'limit' => 10,
+ );
+ $references = node_reference_potential_references($field, $options);
+
+ $matches = array();
+ foreach ($references as $id => $row) {
+ // Markup is fine in autocompletion results (might happen when rendered
+ // through Views) but we want to remove hyperlinks.
+ $suggestion = preg_replace('/([^<]*)<\/a>/', '$2', $row['rendered']);
+ // Add a class wrapper for a few required CSS overrides.
+ $matches[$row['title'] . " [nid:$id]"] = '
' . t("The field is currently configured to use the 'Master' display of the view %view_name.", array('%view_name' => $view_settings['view_name']));
+ $description .= '
' . t("It is highly recommended that you:
- edit this view and create a new display using the 'References' display type,
- update the field settings to explicitly select the correct view and display.");
+ $description .= '
' . t("The field will work correctly until then, but submitting this form might inadvertently change the field settings.") . '
Only views with a display of type "References" are eligible.') . '
'),
+ );
+
+ $default = implode(', ', $view_settings['args']);
+ $form['view']['args'] = array(
+ '#type' => 'textfield',
+ '#title' => t('View arguments'),
+ '#default_value' => $default,
+ '#required' => FALSE,
+ '#description' => t('Provide a comma separated list of arguments to pass to the view.'),
+ );
+ }
+ else {
+ $form['view']['no_view_help'] = array(
+ '#markup' => '
', $summary);
+}
+
+
+/**
+ * Implements hook_field_formatter_prepare_view().
+ *
+ * Preload all user referenced by items using 'full entity' formatters.
+ */
+function user_reference_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
+ // Load the referenced users, except for the 'user_reference_uid' which does
+ // not need full objects.
+
+ // Collect ids to load.
+ $ids = array();
+ foreach ($displays as $id => $display) {
+ if ($display['type'] != 'user_reference_uid') {
+ foreach ($items[$id] as $delta => $item) {
+ if ($item['access']) {
+ $ids[$item['uid']] = $item['uid'];
+ }
+ }
+ }
+ }
+ $entities = user_load_multiple($ids);
+
+ // Add the loaded user objects to the items.
+ foreach ($displays as $id => $display) {
+ if ($display['type'] != 'user_reference_uid') {
+ foreach ($items[$id] as $delta => $item) {
+ if ($item['access']) {
+ $items[$id][$delta]['user'] = $entities[$item['uid']];
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Implements hook_field_formatter_view().
+ */
+function user_reference_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+ $settings = $display['settings'];
+ $result = array();
+
+ // @todo Optimisation: use hook_field_formatter_prepare_view() to load
+ // user names or full user entities in 'multiple' mode.
+
+ // Collect the list of user ids.
+ $uids = array();
+ foreach ($items as $delta => $item) {
+ $uids[$item['uid']] = $item['uid'];
+ }
+
+ switch ($display['type']) {
+ case 'user_reference_default':
+ case 'user_reference_plain':
+ foreach ($items as $delta => $item) {
+ if ($item['access']) {
+ $user = $item['user'];
+ $label = entity_label('user', $user);
+ if ($display['type'] == 'user_reference_default') {
+ $uri = entity_uri('user', $user);
+ $result[$delta] = array(
+ '#type' => 'link',
+ '#title' => $label,
+ '#href' => $uri['path'],
+ '#options' => $uri['options'],
+ );
+ }
+ else {
+ $result[$delta] = array(
+ '#markup' => check_plain($label),
+ );
+ }
+ }
+ }
+ break;
+
+ case 'user_reference_user':
+ $view_mode = $display['settings']['user_reference_view_mode'];
+ // To prevent infinite recursion caused by reference cycles, we store
+ // diplayed accounts in a recursion queue.
+ $recursion_queue = &drupal_static(__FUNCTION__, array());
+
+ // If no 'referencing entity' is set, we are starting a new 'reference
+ // thread' and need to reset the queue.
+ // @todo Bug: $entity->referencing_entity on accounts referenced in a different
+ // thread on the page. E.g: 1 references 1+2 / 2 references 1+2 / visit homepage.
+ // We'd need a more accurate way...
+ if (!isset($entity->referencing_entity)) {
+ $recursion_queue = array();
+ }
+
+ // The recursion queue only needs to track nodes.
+ if ($entity_type == 'user') {
+ list($id) = entity_extract_ids($entity_type, $entity);
+ $recursion_queue[$id] = $id;
+ }
+
+ // Check the recursion queue to determine which accounts should be fully
+ // displayed, and which accounts will only be displayed as a username.
+ $users_display = array();
+ foreach ($items as $delta => $item) {
+ if ($item['access'] && !isset($recursion_queue[$item['uid']])) {
+ $users_display[$item['uid']] = $item['user'];
+ }
+ }
+
+ // Load and build the fully displayed nodes.
+ if ($users_display) {
+ $users_built = array('users' => array('#sorted' => TRUE));
+ foreach ($users_display as $uid => $account) {
+ $users_display[$uid]->referencing_entity = $entity;
+ $users_display[$uid]->referencing_field = $field['field_name'];
+ $users_built['users'][$account->uid] = user_view($account, $settings['user_reference_view_mode']);
+ }
+ }
+
+ // Assemble the render array.
+ foreach ($items as $delta => $item) {
+ if ($item['access']) {
+ if (isset($users_display[$item['uid']])) {
+ $result[$delta] = $users_built['users'][$item['uid']];
+ }
+ else {
+ $account = $item['user'];
+ $label = entity_label('user', $user);
+ $uri = entity_uri('user', $account);
+ $result[$delta] = array(
+ '#type' => 'link',
+ '#title' => $label,
+ '#href' => $uri['path'],
+ '#options' => $uri['options'],
+ );
+ if (!$account->status) {
+ $result[$delta]['#prefix'] = '';
+ $result[$delta]['#suffix'] = '';
+ }
+ }
+ }
+ }
+ break;
+
+ case 'user_reference_uid':
+ foreach ($items as $delta => $item) {
+ if ($item['access']) {
+ $result[$delta] = array(
+ '#markup' => $item['uid'],
+ );
+ }
+ }
+ break;
+
+ case 'user_reference_path':
+ foreach ($items as $delta => $item) {
+ if ($item['access']) {
+ $uri = entity_uri('user', $item['user']);
+ $options = array(
+ 'absolute' => $settings['absolute'],
+ 'alias' => !$settings['alias'],
+ );
+
+ $options += $uri['options'];
+ $result[$delta] = array(
+ '#markup' => url($uri['path'], $options),
+ );
+ }
+ }
+ break;
+ }
+
+ return $result;
+}
+
+/**
+ * Helper function for widgets and formatters.
+ *
+ * Store user names collected in the curent request.
+ */
+function _user_reference_get_user_names($uids, $known_titles = array()) {
+ $titles = &drupal_static(__FUNCTION__, array());
+
+ // Save titles we receive.
+ $titles += $known_titles;
+
+ // Collect nids to retrieve from database.
+ $uids_query = array();
+ foreach ($uids as $uid) {
+ if (!isset($titles[$uid])) {
+ $uids_query[] = $uid;
+ }
+ }
+ if ($uids_query) {
+ $query = db_select('users', 'u')
+ ->fields('u', array('uid', 'name'))
+ ->condition('u.uid', $uids);
+ $titles += $query->execute()->fetchAllKeyed();
+ }
+
+ // Build the results array.
+ $return = array();
+ foreach ($uids as $uid) {
+ $return[$uid] = isset($titles[$uid]) ? $titles[$uid] : '';
+ }
+
+ return $return;
+}
+
+/**
+ * Implements hook_field_widget_info().
+ */
+function user_reference_field_widget_info() {
+ return array(
+ 'user_reference_autocomplete' => array(
+ 'label' => t('Autocomplete text field'),
+ 'description' => t('Display the list of referenceable users as a textfield with autocomplete behaviour.'),
+ 'field types' => array('user_reference'),
+ 'settings' => array(
+ 'autocomplete_match' => 'contains',
+ 'size' => 60,
+ 'autocomplete_path' => 'user_reference/autocomplete',
+ ),
+ ),
+ );
+}
+
+/**
+ * Implements hook_field_widget_info_alter().
+ */
+function user_reference_field_widget_info_alter(&$info) {
+ $info['options_select']['field types'][] = 'user_reference';
+ $info['options_buttons']['field types'][] = 'user_reference';
+}
+
+/**
+ * Implements hook_field_widget_settings_form().
+ */
+function user_reference_field_widget_settings_form($field, $instance) {
+ $widget = $instance['widget'];
+ $defaults = field_info_widget_settings($widget['type']);
+ $settings = array_merge($defaults, $widget['settings']);
+
+ $form = array();
+ if ($widget['type'] == 'user_reference_autocomplete') {
+ $form['autocomplete_match'] = array(
+ '#type' => 'select',
+ '#title' => t('Autocomplete matching'),
+ '#default_value' => $settings['autocomplete_match'],
+ '#options' => array(
+ 'starts_with' => t('Starts with'),
+ 'contains' => t('Contains'),
+ ),
+ '#description' => t('Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of users.'),
+ );
+ $form['size'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Size of textfield'),
+ '#default_value' => $settings['size'],
+ '#element_validate' => array('_element_validate_integer_positive'),
+ '#required' => TRUE,
+ );
+ }
+ return $form;
+}
+
+/**
+ * Implements hook_field_widget_form().
+ */
+function user_reference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+ switch ($instance['widget']['type']) {
+ case 'user_reference_autocomplete':
+ $element += array(
+ '#type' => 'textfield',
+ '#default_value' => isset($items[$delta]['uid']) ? $items[$delta]['uid'] : NULL,
+ '#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'],
+ '#size' => $instance['widget']['settings']['size'],
+ '#element_validate' => array('user_reference_autocomplete_validate'),
+ '#value_callback' => 'user_reference_autocomplete_value',
+ );
+ break;
+ }
+ return array('uid' => $element);
+}
+
+/**
+ * Value callback for a user_reference autocomplete element.
+ *
+ * Substitute in the user name for the uid.
+ */
+function user_reference_autocomplete_value($element, $input = FALSE, $form_state) {
+ if ($input === FALSE) {
+ // We're building the displayed 'default value': expand the raw uid into
+ // "user name [uid:n]".
+ $uid = $element['#default_value'];
+ if (!empty($uid)) {
+ $q = db_select('users', 'u');
+ $q->addField('u', 'name');
+
+ $q->condition('u.uid', $uid)
+ ->range(0, 1);
+ $result = $q->execute();
+ // @todo If no result (user doesn't exist).
+ $value = $result->fetchField();
+ $value .= ' [uid:' . $uid . ']';
+ return $value;
+ }
+ }
+}
+
+/**
+ * Validation callback for a user_reference autocomplete element.
+ */
+function user_reference_autocomplete_validate($element, &$form_state, $form) {
+ $field = field_widget_field($element, $form_state);
+ $instance = field_widget_instance($element, $form_state);
+
+ $value = $element['#value'];
+ $uid = NULL;
+
+ if (!empty($value)) {
+ // Check whether we have an explicit "[uid:n]" input.
+ preg_match('/^(?:\s*|(.*) )?\[\s*uid\s*:\s*(\d+)\s*\]$/', $value, $matches);
+ if (!empty($matches)) {
+ // Explicit uid. Check that the 'name' part matches the actual name for
+ // the uid.
+ list(, $name, $uid) = $matches;
+ if (!empty($name)) {
+ $names = _user_reference_get_user_names(array($uid));
+ if ($name != $names[$uid]) {
+ form_error($element, t('%name: name mismatch. Please check your selection.', array('%name' => $instance['label'])));
+ }
+ }
+ }
+ else {
+ // No explicit uid (the submitted value was not populated by autocomplete
+ // selection). Get the uid of a referencable user from the entered name.
+ $options = array(
+ 'string' => $value,
+ 'match' => 'equals',
+ 'limit' => 1,
+ );
+ $references = user_reference_potential_references($field, $options);
+ if ($references) {
+ // @todo The best thing would be to present the user with an
+ // additional form, allowing the user to choose between valid
+ // candidates with the same name. ATM, we pick the first
+ // matching candidate...
+ $uid = key($references);
+ }
+ else {
+ form_error($element, t('%name: found no valid user with that name.', array('%name' => $instance['label'])));
+ }
+ }
+ }
+
+ // Set the element's value as the user id that was extracted from the entered
+ // input.
+ form_set_value($element, $uid, $form_state);
+}
+
+/**
+ * Implements hook_field_widget_error().
+ */
+function user_reference_field_widget_error($element, $error, $form, &$form_state) {
+ form_error($element['uid'], $error['message']);
+}
+
+/**
+ * Builds a list of referenceable users suitable for the '#option' FAPI property.
+ *
+ * Warning: the function does NOT take care of encoding or escaping the user
+ * names. Proper massaging needs to be performed by the caller, according to
+ * the destination FAPI '#type' (radios / checkboxes / select).
+ *
+ * @param $field
+ * The field definition.
+ *
+ * @return
+ * An array of referenceable user names, keyed by user id.
+ */
+function _user_reference_options($field, $flat = TRUE) {
+ $references = user_reference_potential_references($field);
+
+ $options = array();
+ foreach ($references as $key => $value) {
+ // The label, displayed in selects and checkboxes/radios, should have HTML
+ // entities unencoded. The widgets (core's options.module) take care of
+ // applying the relevant filters (strip_tags() or filter_xss()).
+ $label = html_entity_decode($value['rendered'], ENT_QUOTES);
+ if (empty($value['group']) || $flat) {
+ $options[$key] = $label;
+ }
+ else {
+ // The group name, displayed in selects, cannot contain tags, and should
+ // have HTML entities unencoded.
+ $group = html_entity_decode(strip_tags($value['group']), ENT_QUOTES);
+ $options[$group][$key] = $label;
+ }
+ }
+
+ return $options;
+}
+
+/**
+ * Retrieves an array of candidate referenceable users.
+ *
+ * This info is used in various places (aloowed values, autocomplete results,
+ * input validation...). Some of them only need the uids, others nid + names,
+ * others yet uid + names + rendered row (for display in widgets).
+ * The array we return contains all the potentially needed information, and lets
+ * consumers use the parts they actually need.
+ *
+ * @param $field
+ * The field definition.
+ * @param $options
+ * An array of options to limit the scope of the returned list. The following
+ * key/value pairs are accepted:
+ * - string: string to filter titles on (used by autocomplete).
+ * - match: operator to match the above string against, can be any of:
+ * 'contains', 'equals', 'starts_with'. Defaults to 'contains'.
+ * - ids: array of specific node ids to lookup.
+ * - limit: maximum size of the the result set. Defaults to 0 (no limit).
+ *
+ * @return
+ * An array of valid users in the form:
+ * array(
+ * uid => array(
+ * 'title' => The user name,
+ * 'rendered' => The text to display in widgets (can be HTML)
+ * ),
+ * ...
+ * )
+ */
+function user_reference_potential_references($field, $options = array()) {
+ // Fill in default options.
+ $options += array(
+ 'string' => '',
+ 'match' => 'contains',
+ 'ids' => array(),
+ 'limit' => 0,
+ );
+
+ $results = &drupal_static(__FUNCTION__, array());
+
+ // Create unique id for static cache.
+ $cid = $field['field_name'] . ':' . $options['match'] . ':'
+ . ($options['string'] !== '' ? $options['string'] : implode('-', $options['ids']))
+ . ':' . $options['limit'];
+ if (!isset($results[$cid])) {
+ $references = FALSE;
+ if (module_exists('views') && !empty($field['settings']['view']['view_name'])) {
+ $references = _user_reference_potential_references_views($field, $options);
+ }
+
+ if ($references === FALSE) {
+ $references = _user_reference_potential_references_standard($field, $options);
+ }
+
+ // Store the results.
+ $results[$cid] = !empty($references) ? $references : array();
+ }
+
+ return $results[$cid];
+}
+
+/**
+ * Helper function for user_reference_potential_references().
+ *
+ * Case of Views-defined referenceable users.
+ */
+function _user_reference_potential_references_views($field, $options) {
+ $settings = $field['settings']['view'];
+ $options['title_field'] = 'name';
+ return references_potential_references_view('user', $settings['view_name'], $settings['display_name'], $settings['args'], $options);
+}
+
+/**
+ * Helper function for user_reference_potential_references().
+ *
+ * List of referenceable users defined by user role and status.
+ */
+function _user_reference_potential_references_standard($field, $options) {
+ // Avoid useless work.
+ $filter_roles = array_filter($field['settings']['referenceable_roles']);
+ $filter_status = array_filter($field['settings']['referenceable_status']);
+ if (!count($filter_status) && !count($filter_roles)) {
+ return array();
+ }
+
+ $query = db_select('users', 'u')
+ // Select the whole record, so that format_username() has enough
+ // information.
+ ->fields('u')
+ ->addMetaData('id', ' _user_reference_potential_references_standard')
+ ->addMetaData('field', $field)
+ ->addMetaData('options', $options);
+
+ // Enable this filter only if any statuses checked (and not both).
+ if (count($filter_status) == 1) {
+ $query->condition('u.status', array_keys($filter_status), 'IN');
+ }
+
+ // Skip filter when "authenticated user" choosen.
+ if ($filter_roles && !isset($filter_roles[DRUPAL_AUTHENTICATED_RID])) {
+ $query->join('users_roles', 'r', 'u.uid = r.uid');
+ $query->condition('r.rid', array_keys($filter_roles), 'IN');
+ }
+
+ if ($options['string'] !== '') {
+ switch ($options['match']) {
+ case 'contains':
+ $query->condition('u.name', '%' . $options['string'] . '%', 'LIKE');
+ break;
+
+ case 'starts_with':
+ $query->condition('u.name', $options['string'] . '%', 'LIKE');
+ break;
+
+ case 'equals':
+ default: // no match type or incorrect match type: use "="
+ $query->condition('u.name', $options['string'], '=');
+ break;
+ }
+ }
+
+ if ($options['ids']) {
+ $query->condition('u.uid', $options['ids'], 'IN');
+ }
+
+ // Explicitly exclude the anonymous user.
+ $query->condition('u.uid', 0, '<>');
+
+ if ($options['limit']) {
+ $query->range(0, $options['limit']);
+ }
+ $query->orderBy('u.name');
+
+ $result = $query->execute()->fetchAll();
+ $references = array();
+ foreach ($result as $account) {
+ $references[$account->uid] = array(
+ 'title' => $account->name,
+ 'rendered' => check_plain(format_username($account)),
+ );
+ }
+ return $references;
+}
+
+/**
+ * Menu callback; Retrieve a pipe delimited string of autocomplete suggestions for existing users
+ */
+function user_reference_autocomplete($entity_type, $bundle, $field_name, $string = '') {
+ $field = field_info_field($field_name);
+ $instance = field_info_instance($entity_type, $field_name, $bundle);
+
+ $options = array(
+ 'string' => $string,
+ 'match' => $instance['widget']['settings']['autocomplete_match'],
+ 'limit' => 10,
+ );
+ $references = user_reference_potential_references($field, $options);
+
+ $matches = array();
+ foreach ($references as $id => $row) {
+ // Markup is fine in autocompletion results (might happen when rendered
+ // through Views) but we want to remove hyperlinks.
+ $suggestion = preg_replace('/([^<]*)<\/a>/', '$2', $row['rendered']);
+ // Remove link tags Add a class wrapper for a few required CSS overrides.
+ $matches[$row['title'] . " [uid:$id]"] = '
' . t("Note: In 'References' displays, all fields will be displayed inline unless an explicit selection of inline fields is made here." );
+ }
+
+ function pre_render($row) {
+ // Force all fields to be inline by default.
+ if (empty($this->options['inline'])) {
+ $fields = $this->view->get_items('field', $this->display->id);
+ $this->options['inline'] = drupal_map_assoc(array_keys($fields));
+ }
+
+ return parent::pre_render($row);
+ }
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/modules/references/views/references_plugin_style.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/modules/references/views/references_plugin_style.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,48 @@
+display->handler->get_option('references_options');
+
+ // Play nice with View UI 'preview' : if the view is not executed through
+ // _*_reference_potential_references_views(), just display the HTML.
+ if (empty($options)) {
+ return parent::render();
+ }
+
+ $title_field = $options['title_field'];
+
+ // Group the rows according to the grouping field, if specified.
+ $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
+
+ // Grab the alias of the 'id' field added by references_plugin_display.
+ $id_field_alias = $this->display->handler->id_field_alias;
+
+ $results = array();
+ $this->view->row_index = 0;
+ foreach ($sets as $title => $records) {
+ foreach ($records as $label => $values) {
+ // Render the row.
+ $rendered = $this->row_plugin->render($values);
+ // Remove linebreaks and extra spaces introduced by templates.
+ $rendered = preg_replace('/\s+/', ' ', trim($rendered));
+
+ // Collect the rendered row, and the raw title value.
+ $results[$values->{$id_field_alias}] = array(
+ 'rendered' => $rendered,
+ 'group' => $title,
+ 'title' => $this->view->field[$title_field]->get_value($values),
+ );
+
+ $this->view->row_index++;
+ }
+ }
+ unset($this->view->row_index);
+
+ return $results;
+ }
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/LICENSE.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/LICENSE.txt Fri Sep 20 11:18:21 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.
+
+ >subject; ?>
+
+
+ >
+
+
+
+ type != 'forum'): ?>
+
+ >
+
+
+
+
+>
+
+
+
+
+ ' . t('Pages') . '
' . theme('item_list', array(
+ 'items' => $items,
+ 'attributes' => array('class' => array('pager')),
+ ));
+ }
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/.bowerrc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/.bowerrc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,3 @@
+{
+ "directory" : "libraries"
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/.gitignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/.gitignore Fri Sep 20 11:18:21 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/.gitignore-contributors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/.gitignore-contributors Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,8 @@
+# This .gitignore file is only relevant for maintainers and contributors. As we
+# are not allowed to host any external libraries on d.o we had to integrate
+# Bower into our workflow. This means that we pull in the external libraries
+# only on demand. This is actually a nice feature, however, in order to not
+# disrupt the git workflow of our users (by adding an actual .gitignore entry
+# for the 'components' folder) we should instead add a .gitignore entry to our
+# global, personal .gitignore files (~/.gitingore) instead.
+ohm/components
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/.jshintrc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/.jshintrc Fri Sep 20 11:18:21 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/.ruby-gemset
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/.ruby-gemset Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,1 @@
+omega
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/.ruby-version
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/.ruby-version Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,1 @@
+1.9.3
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/Gemfile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/Gemfile Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,26 @@
+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.
+
+ # 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/Gemfile.lock
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/Gemfile.lock Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,72 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ addressable (2.3.5)
+ breakpoint (2.0.5)
+ compass (>= 0.12.1)
+ sass (>= 3.2.0)
+ chunky_png (1.2.8)
+ color-schemer (0.2.5)
+ compass (~> 0.12)
+ compass-blend-modes (~> 0.0.2)
+ compass (0.12.2)
+ chunky_png (~> 1.2)
+ fssm (>= 0.2.7)
+ sass (~> 3.1)
+ compass-blend-modes (0.0.2)
+ compass
+ compass-normalize (1.4.3)
+ compass (>= 0.12.0)
+ compass-rgbapng (0.2.1)
+ chunky_png (>= 0.8.0)
+ compass (>= 0.10.0)
+ compass-validator (3.0.1)
+ css_parser (1.3.4)
+ addressable
+ ffi (1.9.0)
+ fssm (0.2.10)
+ oily_png (1.1.0)
+ chunky_png (~> 1.2.7)
+ rb-fchange (0.0.6)
+ ffi
+ rb-fsevent (0.9.3)
+ rb-inotify (0.9.0)
+ ffi (>= 0.5.0)
+ sass (3.2.9)
+ sass-globbing (1.1.0)
+ sass (>= 3.1)
+ sassy-strings (0.3.1)
+ compass (>= 0.12.2)
+ singularitygs (1.0.8)
+ breakpoint (>= 2.0.1)
+ compass (>= 0.12.2)
+ sass (>= 3.2.1)
+ susy (1.0.9)
+ compass (>= 0.12.2)
+ sass (>= 3.2.0)
+ toolkit (1.3.3)
+ breakpoint (>= 2.0.2)
+ color-schemer (>= 0.2.3)
+ compass (>= 0.12.2)
+ sassy-strings (>= 0.1)
+ singularitygs (>= 1.0.7)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ breakpoint
+ compass
+ compass-normalize
+ compass-rgbapng
+ compass-validator
+ css_parser
+ oily_png
+ rb-fchange
+ rb-fsevent
+ rb-inotify (~> 0.9)
+ sass
+ sass-globbing
+ singularitygs
+ susy
+ toolkit
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/Gruntfile.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/Gruntfile.js Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,74 @@
+'use strict';
+
+module.exports = function (grunt) {
+
+ grunt.initConfig({
+ watch: {
+ options: {
+ livereload: true
+ },
+ sass: {
+ files: ['sass/{,**/}*.{scss,sass}'],
+ tasks: ['compass']
+ },
+ images: {
+ files: ['images/**']
+ },
+ css: {
+ files: ['stylesheets/{,**/}*.css']
+ },
+ js: {
+ files: ['js/{,**/}*.js', '!js/{,**/}*.js'],
+ tasks: ['jshint', 'uglify:dev']
+ }
+ },
+
+ compass: {
+ all: {
+ options: {
+ environment: 'production',
+ force: true,
+ config: 'config.rb',
+ bundleExec: true
+ }
+ }
+ },
+
+ jshint: {
+ options: {
+ jshintrc: '.jshintrc'
+ },
+ all: ['js/{,**/}*.js', '!js/{,**/}*.min.js']
+ },
+
+ uglify: {
+ options: {
+ mangle: false,
+ compress: false
+ },
+ all: {
+ files: {
+ 'js/jquery.matchmedia.min.js': ['js/jquery.matchmedia.js'],
+ 'js/jquery.resizeend.min.js': ['js/jquery.resizeend.js'],
+ 'js/jquery.scrollable.min.js': ['js/jquery.matchmedia.js'],
+ 'js/omega.admin.min.js': ['js/omega.admin.js'],
+ 'js/omega.indicator.min.js': ['js/omega.indicator.js'],
+ 'js/omega.mediaqueries.min.js': ['js/omega.mediaqueries.js'],
+ 'js/omega.messages.min.js': ['js/omega.messages.js']
+ }
+ }
+ }
+ });
+
+ grunt.loadNpmTasks('grunt-contrib-watch');
+ grunt.loadNpmTasks('grunt-contrib-compass');
+ grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+
+ grunt.registerTask('build', [
+ 'uglify',
+ 'compass',
+ 'jshint'
+ ]);
+
+};
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/README.md
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/README.md Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,19 @@
+# Omega base theme
+
+Omega 4.x is a modern, [Sass](http://sass-lang.com/) and [Compass](http://compass-style.org/) enabled Drupal 7 base theme.
+
+## Installation
+
+In order to install Omega 4.x, simply place it in your sites theme folder (normally located at sites/all/themes). Omega 4.x is a base theme and as such should **never** be used or modified directly. Instead, you should use the [sub-theming functionality](https://drupal.org/node/225125) provided by Drupal.
+
+The easiest way to create a new Omega-based sub-theme is by using [Drush](http://drupal.org/project/drush). Omega comes with a very easy-to-use Drush command for generating sub-themes through a command-line wizard. You can start the sub-theme creation wizard by invoking `drush omega-wizard` in the command-line.
+
+## Documentation
+
+The [Omega 4.x documentation](https://drupal.org/node/1768686) is hosted on drupal.org as part of the handbook section. Please note that we are still in the process of writing the documentation. If you want to get involved, please contact us.
+
+## Maintainance
+
+This version of the Omega theme is maintained by [Sebastian Siemssen](http://drupal.org/user/761344) ([@thefubhy](http://twitter.com/thefubhy)) and [Matt Smith](http://drupal.org/user/1012210) ([@splatio_](http://twitter.com/splatio_))
+
+If you wish to get involved, visit us in [#drupal-omega](irc://chat.freenode.net:6667/drupal-omega) on IRC or send us a message through the issue queue or our personal contact forms on [drupal.org](http://drupal.org).
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/apple-touch-icon-precomposed-114x114.png
Binary file sites/all/themes/omega/omega/apple-touch-icon-precomposed-114x114.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/apple-touch-icon-precomposed-144x144.png
Binary file sites/all/themes/omega/omega/apple-touch-icon-precomposed-144x144.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/apple-touch-icon-precomposed-72x72.png
Binary file sites/all/themes/omega/omega/apple-touch-icon-precomposed-72x72.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/apple-touch-icon-precomposed.png
Binary file sites/all/themes/omega/omega/apple-touch-icon-precomposed.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/bower.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/bower.json Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,11 @@
+{
+ "name": "omega",
+ "version": "1.0.0",
+ "dependencies": {
+ "respond": "fubhy/respond",
+ "selectivizr": "fubhy/selectivizr",
+ "html5shiv": "fubhy/html5shiv",
+ "matchmedia": "fubhy/matchmedia",
+ "pie": "fubhy/pie"
+ }
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/config.rb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/config.rb Fri Sep 20 11:18:21 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/layouts/epiqo/epiqo.layout.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/layouts/epiqo/epiqo.layout.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,4 @@
+/*
+ Mixins are slightly modified from Benjamin Doherty's first implementations: http://gist.github.com/377912
+ rgba-background mixin can now be passed an option $dir variable
+*/
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/layouts/simple/simple.layout.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/layouts/simple/simple.layout.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * _layout.scss
+ *
+ * Styling of the "simple" layout demonstrating the Compass grid extension Susy
+ * and building mobile first layouts.
+ ******************************************************************************/
+.l-header,
+.l-main,
+.l-footer {
+ *zoom: 1;
+ max-width: 1190px;
+ _width: 1190px;
+ padding-left: 5px;
+ padding-right: 5px;
+ margin-left: auto;
+ margin-right: auto;
+ margin-bottom: 20px;
+}
+.l-header:after,
+.l-main:after,
+.l-footer:after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+.l-region--highlighted,
+.l-region--help,
+.l-region--sidebar-first,
+.l-region--sidebar-second {
+ margin-bottom: 20px;
+}
+
+@media (min-width: 44em) {
+ .l-header,
+ .l-main,
+ .l-footer {
+ max-width: 1190px;
+ }
+
+ .l-branding {
+ width: 32.20339%;
+ float: left;
+ margin-right: 1.69492%;
+ }
+
+ .l-region--header {
+ width: 66.10169%;
+ float: right;
+ margin-right: 0;
+ }
+
+ .l-region--navigation {
+ clear: both;
+ }
+
+ .sidebar-first .l-content,
+ .sidebar-second .l-content,
+ .two-sidebars .l-content {
+ width: 66.10169%;
+ float: left;
+ margin-right: 1.69492%;
+ }
+ .sidebar-first .l-region--sidebar-first,
+ .sidebar-first .l-region--sidebar-second,
+ .sidebar-second .l-region--sidebar-first,
+ .sidebar-second .l-region--sidebar-second,
+ .two-sidebars .l-region--sidebar-first,
+ .two-sidebars .l-region--sidebar-second {
+ width: 32.20339%;
+ float: right;
+ margin-right: 0;
+ }
+ .sidebar-first .l-region--sidebar-second,
+ .sidebar-second .l-region--sidebar-second,
+ .two-sidebars .l-region--sidebar-second {
+ clear: right;
+ }
+}
+@media (min-width: 70em) {
+ .l-header,
+ .l-main,
+ .l-footer {
+ max-width: 1190px;
+ }
+
+ .l-branding {
+ width: 36.70886%;
+ float: left;
+ margin-right: 1.26582%;
+ }
+
+ .l-region--header {
+ width: 62.02532%;
+ float: right;
+ margin-right: 0;
+ }
+
+ .sidebar-first .l-content {
+ width: 74.68354%;
+ float: right;
+ margin-right: 0;
+ }
+ .sidebar-first .l-region--sidebar-first {
+ width: 24.05063%;
+ float: left;
+ margin-right: 1.26582%;
+ }
+
+ .sidebar-second .l-content {
+ width: 74.68354%;
+ float: left;
+ margin-right: 1.26582%;
+ }
+ .sidebar-second .l-region--sidebar-second {
+ width: 24.05063%;
+ float: right;
+ margin-right: 0;
+ clear: none;
+ }
+
+ .two-sidebars .l-content {
+ width: 49.36709%;
+ float: left;
+ margin-right: 1.26582%;
+ margin-left: 25.31646%;
+ }
+ .two-sidebars .l-region--sidebar-first,
+ .two-sidebars .l-region--sidebar-second {
+ width: 24.05063%;
+ float: left;
+ margin-right: 1.26582%;
+ }
+ .two-sidebars .l-region--sidebar-first {
+ margin-left: -75.94937%;
+ }
+ .two-sidebars .l-region--sidebar-second {
+ float: right;
+ margin-right: 0;
+ clear: none;
+ }
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/aggregator/aggregator.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/aggregator/aggregator.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,7 @@
+/**
+ * @file
+ * Aggregator theme CSS for right to left languages.
+ */
+.feed-source .feed-icon {
+ float: left;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/aggregator/aggregator.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/aggregator/aggregator.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,9 @@
+/**
+ * @file
+ * Aggregator theme CSS.
+ */
+.feed-source .feed-icon {
+ float: right;
+ /* LTR */
+ display: block;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/block/block.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/block/block.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,14 @@
+/**
+ * @file
+ * Styles for the block admin page.
+ */
+.blocks-admin .region-title {
+ font-weight: bold;
+}
+.blocks-admin .region-message {
+ font-weight: normal;
+ color: #999;
+}
+.blocks-admin .region-populated {
+ display: none;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/block/block.demo.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/block/block.demo.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,38 @@
+/**
+ * @file
+ * Styles for the block demo page.
+ */
+.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;
+ -webkit-border-radius: 0 0 10px 10px;
+ -moz-border-radius: 0 0 10px 10px;
+ -ms-border-radius: 0 0 10px 10px;
+ -o-border-radius: 0 0 10px 10px;
+ border-radius: 0 0 10px 10px;
+}
+
+.block-demo-backlink:hover {
+ text-decoration: underline;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/book/book.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/book/book.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,29 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/book/book.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/book/book.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,17 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/book/book.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/book/book.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,29 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/color/color.admin-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/color/color.admin-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,56 @@
+/**
+ * @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: url('../../../images/modules/color/hook-rtl.png?1378983654') 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/color/color.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/color/color.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,108 @@
+/**
+ * @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: url('../../../images/modules/color/hook.png?1378983654') 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: url('../../../images/modules/color/lock.png?1378983654') 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/comment/comment.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/comment/comment.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Right-to-left comment module look and feel styling.
+ */
+.indented {
+ margin-left: 0;
+ margin-right: 25px;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/comment/comment.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/comment/comment.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Comment module look and feel styling.
+ */
+.indented {
+ margin-left: 25px;
+ /* LTR */
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/contextual/contextual.base-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/contextual/contextual.base-rtl.css Fri Sep 20 11:18:21 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/contextual/contextual.base.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/contextual/contextual.base.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,41 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/contextual/contextual.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/contextual/contextual.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,16 @@
+/**
+ * @file
+ * Styling for contextual links look and feel.
+ */
+/**
+ * Contextual links.
+ */
+.contextual-links {
+ left: 0;
+ right: auto;
+ -webkit-border-radius: 0 4px 4px 4px;
+ -moz-border-radius: 0 4px 4px 4px;
+ -ms-border-radius: 0 4px 4px 4px;
+ -o-border-radius: 0 4px 4px 4px;
+ border-radius: 0 4px 4px 4px;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/contextual/contextual.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/contextual/contextual.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,108 @@
+/**
+ * @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.
+ */
+/**
+ * Contextual link wrappers
+ */
+.contextual-links-region-active {
+ outline: #999 dashed 1px;
+}
+
+.contextual-links-wrapper {
+ font-size: 12px !important;
+}
+.contextual-links-wrapper 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 url('../../../images/modules/contextual/gear-select.png?1378983654') no-repeat 2px 0 !important;
+ border: 1px solid transparent !important;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ -ms-border-radius: 4px;
+ -o-border-radius: 4px;
+ 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;
+ -moz-border-radius-bottomleft: 0;
+ -webkit-border-bottom-left-radius: 0;
+ border-bottom-left-radius: 0;
+ -moz-border-radius-bottomright: 0;
+ -webkit-border-bottom-right-radius: 0;
+ border-bottom-right-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;
+ -webkit-border-radius: 4px 0 4px 4px;
+ -moz-border-radius: 4px 0 4px 4px;
+ -ms-border-radius: 4px 0 4px 4px;
+ -o-border-radius: 4px 0 4px 4px;
+ border-radius: 4px 0 4px 4px;
+ /* LTR */
+ text-align: left;
+ white-space: nowrap;
+}
+.contextual-links li {
+ margin: 0 !important;
+ padding: 0 !important;
+ line-height: 100%;
+ list-style: none;
+ list-style-image: none;
+}
+.contextual-links a {
+ display: block;
+ margin: 0 !important;
+ padding: 5px 10px !important;
+ color: #333 !important;
+ font-size: 12px !important;
+}
+.contextual-links a:hover {
+ background-color: #bfdcee !important;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/field/field.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/field/field.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,11 @@
+/**
+ * @file
+ * Styling for contextual links behaviour and structure.
+ */
+/**
+ * Field display.
+ */
+.field--label-inline .field__label,
+.field--label-inline .field__items {
+ float: right;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/field/field.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/field/field.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,16 @@
+/**
+ * @file
+ * Styling for contextual links behaviour and structure.
+ */
+/**
+ * Field display.
+ */
+.field__label {
+ font-weight: bold;
+}
+
+.field--label-inline .field__label,
+.field--label-inline .field__items {
+ float: left;
+ /* LTR */
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/field_ui/field_ui.admin-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/field_ui/field_ui.admin-rtl.css Fri Sep 20 11:18:21 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 */
+}
+.field-ui-overview .add-new .label-input {
+ float: right;
+ /* LTR */
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/field_ui/field_ui.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/field_ui/field_ui.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,44 @@
+/**
+ * @file
+ * Stylesheet for the Field UI module.
+ */
+/**
+ *'Manage fields' and 'Manage display' overviews.
+ */
+.field-ui-overview {
+ /* Add New Row */
+ /* Hidden Messages */
+}
+.field-ui-overview .add-new td {
+ vertical-align: top;
+}
+.field-ui-overview .add-new .label-input {
+ float: left;
+ /* LTR */
+}
+.field-ui-overview .add-new .tabledrag-changed {
+ display: none;
+}
+.field-ui-overview .add-new .form-type-machine-name .description {
+ white-space: normal;
+}
+.field-ui-overview .region-add-new-title {
+ display: none;
+}
+.field-ui-overview .region-populated {
+ display: none;
+}
+
+/**
+ * 'Manage display' overview
+ */
+.field-display-overview .field-formatter-settings-editing td {
+ vertical-align: top;
+}
+.field-display-overview .field-formatter-settings-editing .field-formatter-type {
+ display: none;
+}
+
+.field-ui-display-overview-form #edit-refresh {
+ display: none;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/file/file.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/file/file.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,24 @@
+/**
+ * @file
+ * Admin stylesheet for file module.
+ */
+/**
+ * Managed file element.
+ */
+.form-managed-file .progress-disabled {
+ float: none;
+ display: inline;
+}
+.form-managed-file .ajax-progress,
+.form-managed-file .throbber {
+ float: none;
+}
+.form-managed-file .ajax-progress-bar {
+ display: none;
+ width: 28em;
+ margin-top: 4px;
+ padding: 0;
+}
+.form-managed-file .ajax-progress-bar .bar {
+ margin: 0;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/filter/filter.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/filter/filter.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,49 @@
+/**
+ * @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;
+}
+.text-format-wrapper .description {
+ margin-top: 0.5em;
+}
+
+/* Filter Format Wrapper. */
+.filter-wrapper {
+ border-top: 0;
+ margin: 0;
+}
+.filter-wrapper .form-item {
+ float: left;
+ padding: 0 0 0.5em 1.5em;
+}
+.filter-wrapper .form-item label {
+ display: inline;
+}
+
+/* More Information Link. */
+.filter-help {
+ float: right;
+ padding: 0 1.5em 0.5em;
+}
+.filter-help a {
+ background: transparent url('../../../images/misc/help.png?1378983654') 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/forum/forum.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/forum/forum.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,9 @@
+/**
+ * @file
+ * Right-to-left styling for the Forum module.
+ */
+.forum-icon {
+ float: right;
+ margin-left: 0;
+ margin-right: 0.4em;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/forum/forum.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/forum/forum.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,34 @@
+/**
+ * @file
+ * Styling for the Forum module.
+ */
+/* Forum Status Icons */
+.forum-icon {
+ float: left;
+ width: 24px;
+ height: 24px;
+ margin-right: 0.4em;
+ background-image: url('../../../images/modules/forum/forum-icons.png?1378983654');
+ 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/image/image.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/image/image.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,70 @@
+/**
+ * @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;
+}
+.preview-image__width .dimension {
+ position: relative;
+ top: 4px;
+}
+
+.preview-image__height {
+ position: absolute;
+ right: -6px;
+ top: -1px;
+ width: 2px;
+ border: 1px solid #666;
+ border-left: none;
+}
+.preview-image__height .dimension {
+ position: absolute;
+ height: 2em;
+ top: 50%;
+ left: 10px;
+ margin-top: -1em;
+}
+
+/**
+ * Image anchor form element.
+ */
+.image-anchor {
+ width: auto;
+}
+.image-anchor .even,
+.image-anchor .odd {
+ background: none;
+}
+.image-anchor td {
+ border: 1px solid #CCC;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/image/image.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/image/image.theme-rtl.css Fri Sep 20 11:18:21 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/image/image.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/image/image.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,21 @@
+/**
+ * @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 */
+}
+.image-widget-data .text-field {
+ width: auto;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/locale/locale.admin-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/locale/locale.admin-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @file
+ * Right to left admin styles for the locale module.
+ */
+.locale-translation-filter-form .form-item-language,
+.locale-translation-filter-form .form-item-translation,
+.locale-translation-filter-form .form-item-group {
+ float: right;
+ padding-left: .8em;
+ padding-right: 0;
+}
+.locale-translation-filter-form .form-actions {
+ float: right;
+ padding: 3ex 1em 0 0;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/locale/locale.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/locale/locale.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,31 @@
+/**
+ * @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,
+.locale-translation-filter-form .form-item-translation,
+.locale-translation-filter-form .form-item-group {
+ float: left;
+ /* LTR */
+ padding-right: .8em;
+ /* LTR */
+ margin: 0.1em;
+ width: 15em;
+ /* Opera 9 Fix. */
+}
+.locale-translation-filter-form .form-type-select select {
+ width: 100%;
+}
+.locale-translation-filter-form .form-actions {
+ float: left;
+ /* LTR */
+ padding: 3ex 0 0 1em;
+ /* LTR */
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/openid/openid.base-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/openid/openid.base-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,8 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/openid/openid.base.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/openid/openid.base.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,15 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/openid/openid.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/openid/openid.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,14 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/openid/openid.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/openid/openid.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,30 @@
+/**
+ * @file
+ * Theme styles for the openid module.
+ */
+.form-item-openid-identifier {
+ display: block;
+}
+.form-item-openid-identifier input {
+ padding-left: 20px;
+ /* LTR */
+ background-image: url('../../../images/modules/openid/login-bg.png?1378983654');
+ background-position: left 50%;
+ /* LTR */
+ background-repeat: no-repeat;
+}
+
+.openid-links li {
+ display: none;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+.openid-links a {
+ padding: 0 0 0 1.5em;
+ /* LTR */
+ background-image: url('../../../images/modules/openid/login-bg.png?1378983654');
+ background-position: left top;
+ /* LTR */
+ background-repeat: no-repeat;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/poll/poll.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/poll/poll.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,13 @@
+/**
+ * @file
+ * Admin styles for the poll module.
+ */
+/* Poll choice form on node form. */
+.poll-choice-table .form-text {
+ display: inline;
+ width: auto;
+}
+.poll-choice-table .choice-flag {
+ white-space: nowrap;
+ width: 4em;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/poll/poll.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/poll/poll.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,16 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/poll/poll.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/poll/poll.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,43 @@
+/**
+ * @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;
+}
+.poll-bars__bar .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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/search/search.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/search/search.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,24 @@
+/**
+ * @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;
+}
+.search-advanced .action {
+ float: right;
+ clear: right;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/search/search.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/search/search.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,31 @@
+/**
+ * @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 */
+}
+.search-advanced .action {
+ float: left;
+ /* LTR */
+ clear: left;
+ /* LTR */
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.admin-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.admin-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,92 @@
+/**
+ * @file
+ * Right to left system wide administration styles.
+ */
+/**
+ * @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;
+}
+.admin .right {
+ float: left;
+}
+.admin .expert-link {
+ margin-left: 0;
+ margin-right: 1em;
+ padding-left: 0;
+ padding-right: 4px;
+ text-align: left;
+}
+
+/**
+ * @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--enabled .theme-selector__screenshot {
+ float: right;
+}
+
+/* Theme Selector Disabled State */
+.theme-selector--disabled {
+ float: right;
+ padding: 20px 20px 20px;
+}
+
+/**
+ * @file
+ * Right to left administration styles for the modules table.
+ */
+/* Module Operation Links */
+.module-link {
+ padding: 1px 20px 1px 0;
+}
+
+.module-link-help {
+ background: url('../../../images/misc/help.png?1378983654') 0 50% no-repeat;
+ /* LTR */
+}
+
+.module-link-permissions {
+ background: url('../../../images/misc/permissions.png?1378983654') 0 50% no-repeat;
+ /* LTR */
+}
+
+.module-link-configure {
+ background: url('../../../images/misc/configure.png?1378983654') 0 50% no-repeat;
+ /* LTR */
+}
+
+/* Module Help */
+.module-help {
+ float: left;
+ margin-left: 0;
+ margin-right: 1em;
+}
+
+/**
+ * @file
+ * Right to left administration styles for the system status report.
+ */
+.merge-up td {
+ padding: 0 28px 8px 6px;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,273 @@
+/**
+ * @file
+ * System wide administration styles.
+ */
+/**
+ * @file
+ * Administration styles for quick inline admin links.
+ */
+small .admin-link:before {
+ content: '[';
+}
+
+small .admin-link:after {
+ content: ']';
+}
+
+/**
+ * @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;
+}
+.admin .left {
+ float: left;
+ /* LTR */
+ width: 47%;
+}
+.admin .right {
+ float: right;
+ /* LTR */
+ width: 47%;
+}
+.admin .expert-link {
+ margin-right: 1em;
+ /* LTR */
+ padding-right: 4px;
+ /* LTR */
+ text-align: right;
+ /* LTR */
+}
+
+/**
+ * @file
+ * Administration styles for the appearance page.
+ */
+/**
+ * Disabled/Enabled Theme Lists
+ */
+.system-themes-list {
+ margin-bottom: 20px;
+}
+.system-themes-list h2 {
+ margin: 0;
+}
+
+.system-themes-list--disabled {
+ padding-top: 20px;
+ border-top: 1px solid #cdcdcd;
+}
+
+/**
+ * Theme Selector
+ */
+.theme-selector {
+ padding-top: 20px;
+}
+.theme-selector 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;
+}
+.theme-selector__operations 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--default .theme-selector__screenshot {
+ border: 1px solid #aaa;
+}
+
+/* Theme Selector Enabled State */
+.theme-selector--enabled {
+ width: 820px;
+}
+.theme-selector--enabled .theme-selector__info {
+ float: right;
+ /* LTR */
+ width: 500px;
+}
+.theme-selector--enabled h3 {
+ margin-top: 0;
+}
+.theme-selector--enabled .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--disabled .theme-selector__info {
+ min-height: 170px;
+}
+.theme-selector--disabled .theme-selector__screenshot {
+ width: 194px;
+ height: 144px;
+ line-height: 144px;
+}
+
+/**
+ * Admin Theme Selector Form
+ */
+.system-themes-admin-form {
+ clear: left;
+}
+
+/**
+ * @file
+ * Administration styles for compact links.
+ */
+.compact-link {
+ margin: 0 0 0.5em 0;
+}
+
+/**
+ * @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: url('../../../images/misc/help.png?1378983654') 0 50% no-repeat;
+ /* LTR */
+}
+
+.module-link-permissions {
+ background: url('../../../images/misc/permissions.png?1378983654') 0 50% no-repeat;
+ /* LTR */
+}
+
+.module-link-configure {
+ background: url('../../../images/misc/configure.png?1378983654') 0 50% no-repeat;
+ /* LTR */
+}
+
+/* Module Help */
+.module-help {
+ float: right;
+ /* LTR */
+ margin-left: 1em;
+ /* LTR */
+}
+
+/**
+ * @file
+ * Administration styles for the system status report.
+ */
+/* Status Icons */
+.system-status-report .status-icon {
+ height: 16px;
+ width: 16px;
+ background-repeat: no-repeat;
+}
+.system-status-report .error .status-icon {
+ background-image: url('../../../images/misc/message-16-error.png?1378983654');
+}
+.system-status-report .warning .status-icon {
+ background-image: url('../../../images/misc/message-16-warning.png?1378983654');
+}
+
+/* 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 */
+}
+
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.base-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.base-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,65 @@
+/**
+ * @file
+ * Right to left system wide base styles.
+ */
+/**
+ * @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;
+}
+
+/**
+ * @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;
+}
+
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.base.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.base.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,289 @@
+/**
+ * @file
+ * System wide base styles.
+ */
+/**
+ * @file
+ * Base styles for autocomplete functionality.
+ *
+ * @see autocomplete.js
+ */
+/* Suggestion list */
+#autocomplete {
+ position: absolute;
+ z-index: 100;
+ overflow: hidden;
+}
+#autocomplete ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ list-style-image: none;
+}
+#autocomplete li {
+ cursor: default;
+ white-space: pre;
+ zoom: 1;
+ /* IE7 */
+}
+
+/* Animated throbber */
+html.js .form-autocomplete {
+ background-image: url('../../../images/misc/throbber.gif?1378983654');
+ background-position: 100% 2px;
+ /* LTR */
+ background-repeat: no-repeat;
+}
+
+html.js .throbbing {
+ background-position: 100% -18px;
+ /* LTR */
+}
+
+/**
+ * @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;
+}
+
+/**
+ * @file
+ * Base styles for the resizable textareas functionality.
+ *
+ * @see textarea.js
+ */
+.form-textarea-wrapper textarea {
+ display: block;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ width: 100%;
+ margin: 0;
+}
+
+.resizable-textarea .grippie {
+ height: 9px;
+ background: #eeeeee url('../../../images/misc/grippie.png?1378983654') no-repeat center 2px;
+ border: 1px solid #ddd;
+ border-top-width: 0;
+ cursor: s-resize;
+ overflow: hidden;
+}
+
+/**
+ * @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;
+}
+.tabledrag-handle .handle {
+ height: 15px;
+ width: 15px;
+ margin: -0.4em 0;
+ padding: 0.4em;
+ background: url('../../../images/misc/draggable.png?1378983654') no-repeat 6px 9px;
+}
+.tabledrag-handle:hover {
+ text-decoration: none;
+}
+
+.tabledrag-handle-hover .handle {
+ background-position: 6px -11px;
+}
+
+/* Indentation */
+.indentation {
+ float: left;
+ /* LTR */
+ width: 20px;
+}
+
+/* Tree Images */
+.tree-child {
+ background: url('../../../images/misc/tree.png?1378983654') no-repeat 12px center;
+ /* LTR */
+}
+
+.tree-child-last {
+ background: url('../../../images/misc/tree-bottom.png?1378983654') no-repeat 12px center;
+ /* LTR */
+}
+
+.tree-child-horizontal {
+ background: url('../../../images/misc/tree.png?1378983654') no-repeat -12px center;
+}
+
+/* Toggle Weight Link */
+.tabledrag-toggle-weight-wrapper {
+ text-align: right;
+ /* LTR */
+}
+
+/**
+ * @file
+ * Base styling for the tableheader behavior.
+ *
+ * @see tableheader.js
+ */
+.sticky-header {
+ margin-top: 0;
+ background-color: #fff;
+}
+
+/**
+ * @file
+ * Base styles for the progress behavior.
+ *
+ * @see progress.js
+ */
+/* Bar */
+.progress .bar {
+ background-color: #fff;
+ border: 1px solid;
+}
+.progress .filled {
+ height: 1.5em;
+ width: 5px;
+ background-color: #000;
+}
+.progress .percentage {
+ float: right;
+ /* LTR */
+}
+
+/* Throbber */
+.ajax-progress {
+ display: inline-block;
+}
+.ajax-progress .throbber {
+ float: left;
+ /* LTR */
+ height: 15px;
+ width: 15px;
+ margin: 2px;
+ background: transparent url('../../../images/misc/throbber.gif?1378983654') no-repeat 0px -18px;
+}
+.ajax-progress .message {
+ padding-left: 20px;
+}
+
+tr .ajax-progress .throbber {
+ margin: 0 2px;
+}
+
+.ajax-progress-bar {
+ width: 16em;
+}
+
+/**
+ * @file
+ * System utility classes.
+ */
+/**
+ * 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 {
+ *zoom: 1;
+}
+.clearfix:after {
+ content: "";
+ display: table;
+ clear: both;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.menus.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.menus.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,25 @@
+/**
+ * @file
+ * Right to left menu and navigational styles.
+ */
+/**
+ * @file
+ * Styles for a hierarchical menu as generated by theme_menu_tree().
+ */
+.menu {
+ text-align: right;
+ /* Menu Item Hierarchy Modifiers */
+}
+.menu .collapsed {
+ list-style-image: url('../../../images/misc/menu-collapsed-rtl.png?1378983654');
+}
+
+/**
+ * @file
+ * Inline links as generated by theme_links().
+ */
+ul.inline li {
+ float: right;
+ margin-right: 0;
+ margin-left: 1em;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.menus.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.menus.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,94 @@
+/**
+ * @file
+ * Menu and navigational styles.
+ */
+/**
+ * @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 */
+}
+.menu .expanded {
+ list-style-image: url('../../../images/misc/menu-expanded.png?1378983654');
+ list-style-type: circle;
+}
+.menu .collapsed {
+ list-style-image: url('../../../images/misc/menu-collapsed.png?1378983654');
+ /* LTR */
+ list-style-type: disc;
+}
+.menu .leaf {
+ list-style-image: url('../../../images/misc/menu-leaf.png?1378983654');
+ list-style-type: square;
+}
+
+/* Menu State Modifiers */
+.active {
+ color: #000;
+}
+
+.menu-disabled {
+ background: #ccc;
+}
+
+/**
+ * @file
+ * Inline links as generated by theme_links().
+ */
+.links--inline {
+ *zoom: 1;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+.links--inline:after {
+ content: "";
+ display: table;
+ clear: both;
+}
+.links--inline li {
+ float: left;
+ /* LTR */
+ margin-right: 1em;
+ /* LTR */
+}
+.links--inline li > a {
+ display: block;
+}
+
+/**
+ * @file
+ * Theme styles for markup generated by theme_menu_local_tasks().
+ */
+/* Tabs */
+.tabs a {
+ background-color: #eee;
+ text-decoration: none;
+}
+.tabs a.active {
+ background-color: #ccc;
+}
+.tabs a:hover, .tabs a:focus {
+ background-color: #bbb;
+}
+
+/* Primary Tabs */
+.tabs--primary {
+ margin-bottom: 1em;
+ border-bottom: 1px solid #bbb;
+}
+.tabs--primary a {
+ padding: 0.3em 0.8em;
+}
+
+/* Secondary Tabs */
+.tabs--secondary a {
+ padding: 0.2em 0.5em;
+ margin: 0.4em 0;
+ font-size: 0.9em;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.messages.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.messages.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,12 @@
+/**
+ * @file
+ * Right to left theme for for system messages.
+ */
+/* Message */
+.messages {
+ padding: 10px 50px 10px 10px;
+ background-position: 99% 8px;
+}
+.messages ul {
+ margin: 0 1em 0 0;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.messages.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.messages.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,74 @@
+/**
+ * @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;
+}
+.messages ul {
+ margin: 0 0 0 1em;
+ /* LTR */
+ padding: 0;
+}
+.messages li {
+ list-style-image: none;
+}
+
+/* Status Messages */
+.messages--status {
+ background-image: url('../../../images/misc/message-24-ok.png?1378983654');
+ border-color: #be7;
+}
+
+.messages--status,
+tr.ok {
+ background-color: #f8fff0;
+}
+
+.messages--status,
+.ok {
+ color: #234600;
+}
+
+/* Warning Messages */
+.messages--warning {
+ background-image: url('../../../images/misc/message-24-warning.png?1378983654');
+ border-color: #ed5;
+}
+
+.messages--warning,
+tr.warning {
+ background-color: #fffce5;
+}
+
+.messages--warning,
+.warning {
+ color: #333;
+}
+
+/* Error Messages */
+.messages--error {
+ background-image: url('../../../images/misc/message-24-error.png?1378983654');
+ border-color: #ed541d;
+}
+
+.messages--error,
+tr.error {
+ background-color: #fef5f1;
+}
+
+.messages--error,
+.error {
+ color: #333;
+}
+
+.error .error {
+ color: #8c2e0b;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,39 @@
+/**
+ * @file
+ * Right to left system wide theme styles.
+ */
+/**
+ * @file
+ * Basic right to left styling for common HTML elements.
+ */
+/* Tables */
+th {
+ padding-left: 1em;
+ padding-right: 0;
+ text-align: right;
+}
+
+/**
+ * @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: url('../../../images/misc/menu-collapsed-rtl.png?1378983654');
+ background-position: 98% 50%;
+}
+
+/**
+ * @file
+ * Right to left theme for the more link.
+ */
+.more-link {
+ text-align: left;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/system/system.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/system/system.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,239 @@
+/**
+ * @file
+ * System wide theme styles.
+ */
+/**
+ * @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;
+}
+
+/**
+ * @file
+ * Theme for autocomplete.
+ *
+ * @see autocomplete.js
+ */
+#autocomplete {
+ background: #fff;
+ border: 1px solid;
+ color: #000;
+}
+#autocomplete .selected {
+ background: #0072b9;
+ color: #fff;
+}
+
+/**
+ * @file
+ * Theme for collapsible fieldsets.
+ *
+ * @see collapse.js
+ */
+html.js fieldset.collapsible .fieldset-legend {
+ padding-left: 15px;
+ /* LTR */
+ background: url('../../../images/misc/menu-expanded.png?1378983654') 5px 65% no-repeat;
+ /* LTR */
+}
+
+html.js fieldset.collapsed {
+ border-bottom-width: 0;
+ border-left-width: 0;
+ border-right-width: 0;
+}
+html.js fieldset.collapsed .fieldset-legend {
+ background-image: url('../../../images/misc/menu-collapsed.png?1378983654');
+ /* LTR */
+ background-position: 5px 50%;
+ /* LTR */
+}
+
+.fieldset-legend .summary {
+ margin-left: 0.5em;
+ color: #999;
+ font-size: 0.9em;
+}
+
+/**
+ * @file
+ * Theme for the tabledrag behavior.
+ *
+ * @see tabledrag.js
+ */
+.drag {
+ background-color: #fffff0;
+}
+
+.drag-previous {
+ background-color: #ffd;
+}
+
+/**
+ * @file
+ * Theme for the progress behavior.
+ *
+ * @see progress.js
+ */
+.progress {
+ font-weight: bold;
+}
+.progress .bar {
+ background: #ccc;
+ border-color: #666;
+ margin: 0 0.2em;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+}
+.progress .filled {
+ background: #0072b9 url('../../../images/misc/progress.gif?1378983654');
+}
+
+/**
+ * @file
+ * Theme for the tableselect behavior.
+ *
+ * @see tableselect.js
+*/
+.selected td {
+ background: #ffc;
+}
+
+.checkbox,
+.checkbox {
+ text-align: center;
+}
+
+/**
+ * @form
+ * Theme for markup generated by Form API.
+ */
+/* Generic Form Items. */
+.form-item,
+.form-actions {
+ margin-bottom: 1em;
+}
+.form-item label,
+.form-actions label {
+ display: block;
+ font-weight: bold;
+}
+.form-item .description,
+.form-actions .description {
+ font-size: 0.85em;
+}
+
+/* Checkboxes and Radios */
+.form-checkboxes .form-item,
+.form-radios .form-item {
+ margin-bottom: 0.4em;
+}
+.form-checkboxes .description,
+.form-radios .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;
+}
+
+/**
+ * @file
+ * Theme for the markup generated by theme_tablesort_indicator().
+ */
+th.active img {
+ display: inline;
+}
+
+td.active {
+ background-color: #ddd;
+}
+
+/**
+ * @file
+ * Theme for more links.
+ */
+.more-link {
+ display: block;
+ text-align: right;
+ /* LTR */
+}
+
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/taxonomy/taxonomy.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/taxonomy/taxonomy.admin.css Fri Sep 20 11:18:21 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/user/user.admin-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/user/user.admin-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,23 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/user/user.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/user/user.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * Administrative styling for the user module.
+ */
+/**
+ * User Permissions Page
+ */
+.user-admin-permissions .module {
+ font-weight: bold;
+}
+.user-admin-permissions .permission {
+ padding-left: 1.5em;
+ /* LTR */
+}
+.user-admin-permissions .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;
+}
+.user-admin-roles .form-item-name {
+ float: left;
+ /* LTR */
+ margin-right: 1em;
+ /* LTR */
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/user/user.base-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/user/user.base-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,4 @@
+/**
+ * @file
+ * Right to left base styles for the user module.
+ */
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/user/user.base.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/user/user.base.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,7 @@
+/**
+ * @file
+ * Base styles for the user module.
+ */
+div.password-confirm {
+ visibility: hidden;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/user/user.theme-rtl.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/user/user.theme-rtl.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,35 @@
+/**
+ * @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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/modules/user/user.theme.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/modules/user/user.theme.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,95 @@
+/**
+ * @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;
+}
+.password-indicator .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;
+}
+.profile .user-picture {
+ float: right;
+ /* LTR */
+ margin: 0 1em 1em 0;
+ /* LTR */
+}
+.profile h3 {
+ border-bottom: 1px solid #ccc;
+}
+.profile dl {
+ margin: 0 0 1.5em 0;
+}
+.profile dt {
+ margin: 0 0 0.2em 0;
+ font-weight: bold;
+}
+.profile dd {
+ margin: 0 0 1em 0;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/omega.admin.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/omega.admin.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,57 @@
+.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;
+}
+div.vertical-tabs .vertical-tabs-panes .vertical-tabs-pane fieldset legend {
+ display: block;
+}
+
+.omega-assets-missing-files {
+ color: #8c2e0b;
+ margin: 1em 0 1em 1.5em;
+}
+.omega-assets-missing-files h3 {
+ font-size: .9em;
+ text-transform: uppercase;
+ margin-bottom: 0;
+}
+
+.omega-layout-selection-wrapper {
+ margin-bottom: 20px;
+ min-height: 75px;
+ position: relative;
+}
+.omega-layout-selection-wrapper .form-item label.option,
+.omega-layout-selection-wrapper .form-item div.description {
+ padding-left: 80px;
+}
+.omega-layout-selection-wrapper 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/omega.development.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/omega.development.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,44 @@
+.omega-browser-width {
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ -ms-border-radius: 5px;
+ -o-border-radius: 5px;
+ border-radius: 5px;
+ background: url('../images/rgbapng/000000bf-5.png?1378988979');
+ 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 {
+ background: url('../images/rgbapng/0000001a-5.png?1378988979');
+ background: rgba(0, 0, 0, 0.1);
+ position: relative;
+ min-height: 29px;
+ outline: 1px dashed #ccc;
+}
+.region--debug:before {
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ -ms-border-radius: 3px;
+ -o-border-radius: 3px;
+ border-radius: 3px;
+ background: url('../images/rgbapng/077dc3bf-5.png?1378988979');
+ background: rgba(7, 125, 195, 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 d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/css/omega.messages.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/css/omega.messages.css Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,20 @@
+@charset "UTF-8";
+div.messages {
+ position: relative;
+}
+
+.close-message {
+ text-shadow: none;
+ position: absolute;
+ right: .4em;
+ top: -.2em;
+ text-decoration: none;
+ color: rgba(0, 0, 0, 0.3);
+}
+.close-message:before {
+ font-size: 1.4em;
+ content: "×";
+}
+.close-message:hover, .close-message:focus, .close-message:active {
+ color: #000;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/favicon.ico
Binary file sites/all/themes/omega/omega/favicon.ico has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/layout-icon-placeholder.png
Binary file sites/all/themes/omega/omega/images/layout-icon-placeholder.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/arrow-asc.png
Binary file sites/all/themes/omega/omega/images/misc/arrow-asc.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/arrow-desc.png
Binary file sites/all/themes/omega/omega/images/misc/arrow-desc.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/configure.png
Binary file sites/all/themes/omega/omega/images/misc/configure.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/draggable.png
Binary file sites/all/themes/omega/omega/images/misc/draggable.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/feed.png
Binary file sites/all/themes/omega/omega/images/misc/feed.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/forum-icons.png
Binary file sites/all/themes/omega/omega/images/misc/forum-icons.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/grippie.png
Binary file sites/all/themes/omega/omega/images/misc/grippie.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/help.png
Binary file sites/all/themes/omega/omega/images/misc/help.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/menu-collapsed-rtl.png
Binary file sites/all/themes/omega/omega/images/misc/menu-collapsed-rtl.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/menu-collapsed.png
Binary file sites/all/themes/omega/omega/images/misc/menu-collapsed.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/menu-expanded.png
Binary file sites/all/themes/omega/omega/images/misc/menu-expanded.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/menu-leaf.png
Binary file sites/all/themes/omega/omega/images/misc/menu-leaf.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-16-error.png
Binary file sites/all/themes/omega/omega/images/misc/message-16-error.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-16-help.png
Binary file sites/all/themes/omega/omega/images/misc/message-16-help.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-16-info.png
Binary file sites/all/themes/omega/omega/images/misc/message-16-info.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-16-ok.png
Binary file sites/all/themes/omega/omega/images/misc/message-16-ok.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-16-warning.png
Binary file sites/all/themes/omega/omega/images/misc/message-16-warning.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-24-error.png
Binary file sites/all/themes/omega/omega/images/misc/message-24-error.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-24-help.png
Binary file sites/all/themes/omega/omega/images/misc/message-24-help.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-24-info.png
Binary file sites/all/themes/omega/omega/images/misc/message-24-info.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-24-ok.png
Binary file sites/all/themes/omega/omega/images/misc/message-24-ok.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/message-24-warning.png
Binary file sites/all/themes/omega/omega/images/misc/message-24-warning.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/permissions.png
Binary file sites/all/themes/omega/omega/images/misc/permissions.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/progress.gif
Binary file sites/all/themes/omega/omega/images/misc/progress.gif has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/throbber.gif
Binary file sites/all/themes/omega/omega/images/misc/throbber.gif has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/tree-bottom.png
Binary file sites/all/themes/omega/omega/images/misc/tree-bottom.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/tree.png
Binary file sites/all/themes/omega/omega/images/misc/tree.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/watchdog-error.png
Binary file sites/all/themes/omega/omega/images/misc/watchdog-error.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/watchdog-ok.png
Binary file sites/all/themes/omega/omega/images/misc/watchdog-ok.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/misc/watchdog-warning.png
Binary file sites/all/themes/omega/omega/images/misc/watchdog-warning.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/modules/color/hook-rtl.png
Binary file sites/all/themes/omega/omega/images/modules/color/hook-rtl.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/modules/color/hook.png
Binary file sites/all/themes/omega/omega/images/modules/color/hook.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/modules/color/lock.png
Binary file sites/all/themes/omega/omega/images/modules/color/lock.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/modules/contextual/gear-select.png
Binary file sites/all/themes/omega/omega/images/modules/contextual/gear-select.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/modules/forum/forum-icons.png
Binary file sites/all/themes/omega/omega/images/modules/forum/forum-icons.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/modules/openid/login-bg.png
Binary file sites/all/themes/omega/omega/images/modules/openid/login-bg.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/rgbapng/0000001a-5.png
Binary file sites/all/themes/omega/omega/images/rgbapng/0000001a-5.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/rgbapng/0000001a.png
Binary file sites/all/themes/omega/omega/images/rgbapng/0000001a.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/rgbapng/000000bf-5.png
Binary file sites/all/themes/omega/omega/images/rgbapng/000000bf-5.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/rgbapng/000000bf.png
Binary file sites/all/themes/omega/omega/images/rgbapng/000000bf.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/rgbapng/077dc3bf-5.png
Binary file sites/all/themes/omega/omega/images/rgbapng/077dc3bf-5.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/images/rgbapng/077dc3bf.png
Binary file sites/all/themes/omega/omega/images/rgbapng/077dc3bf.png has changed
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/includes/assets/assets.extension.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/includes/assets/assets.extension.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,3 @@
+name = Assets
+description = There should be a description here.
+enabled = TRUE
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/includes/assets/assets.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/includes/assets/assets.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,69 @@
+ $info) {
+ if (!empty($settings[$library]['status'])) {
+ $registry['html']['libraries'][$library] = array(
+ 'attached' => array(),
+ 'settings' => $settings[$library],
+ 'callbacks' => isset($info['callbacks']) ? array_unique($info['callbacks']) : FALSE,
+ );
+
+ if (isset($settings[$library]['variant']) && $variant = $settings[$library]['variant']) {
+ $registry['html']['libraries'][$library]['attached'] = $info['variants'][$variant]['files'];
+ }
+ else {
+ $registry['html']['libraries'][$library]['attached'] = $info['files'];
+ }
+ }
+ }
+ }
+
+ if (!empty($registry['html']['libraries'])) {
+ $registry['html']['preprocess functions'][] = 'omega_extension_assets_attach_libraries';
+ }
+}
+
+/**
+ * Extension callback for attaching enabled libraries.
+ */
+function omega_extension_assets_attach_libraries(&$variables) {
+ $registry = theme_get_registry();
+
+ // Check if there are any enabled libraries.
+ $libraries = module_exists('devel_themer') ? $registry['html']['original']['libraries'] : $registry['html']['libraries'];
+ foreach ($libraries as $library => $info) {
+ drupal_process_attached(array('#attached' => $info['attached']));
+
+ if (!empty($info['callbacks'])) {
+ foreach ($info['callbacks'] as $callback) {
+ $callback($library, $info['settings']);
+ }
+ }
+ }
+}
+
+/**
+ * Library callback for checking if CSS aggregation is enabled.
+ */
+function omega_extension_library_requirements_css_aggregation($library, $settings) {
+ if ((!variable_get('preprocess_css', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update'))) {
+ if (user_access('administer site configuration') && flood_is_allowed('omega_' . $GLOBALS['theme'] . '_aggregation_required', 3, 3600, $library)) {
+ $libraries = omega_theme_libraries_info();
+ $info = $libraries[$library];
+
+ // Tell the user that the library does not work without CSS aggregation.
+ flood_register_event('omega_' . $GLOBALS['theme'] . '_aggregation_required', 3600, $library);
+ drupal_set_message(t('The %library library requires aggregated CSS files to work properly. You can enable CSS aggregation in the performance settings.', array('!url' => url('admin/config/development/performance'), '%library' => $info['name'])), 'warning');
+ }
+ }
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/includes/assets/assets.settings.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/includes/assets/assets.settings.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,244 @@
+ 'textarea',
+ '#title' => t('Move JS files to the footer'),
+ '#description' => t("Enter one file per line. The '*' character is a wildcard. Each path is relative to a module, theme, profile, theme engine or the 'misc' folder."),
+ // The paths are stored in an array.
+ '#default_value' => implode("\n", (array) omega_theme_get_setting('omega_js_footer', array())),
+ );
+
+ $element['omega_css_exclude'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Exclude CSS files'),
+ '#description' => t("Enter one file per line. The '*' character is a wildcard. Each path is relative to a module, theme, profile, theme engine or the 'misc' folder."),
+ // The paths are stored in an array.
+ '#default_value' => implode("\n", (array) omega_theme_get_setting('omega_css_exclude', array())),
+ );
+
+ $element['omega_js_exclude'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Exclude JS files'),
+ '#description' => t("Enter one file per line. The '*' character is a wildcard. Each path is relative to a module, theme, profile, theme engine or the 'misc' folder."),
+ // The paths are stored in an array.
+ '#default_value' => implode("\n", (array) omega_theme_get_setting('omega_js_exclude', array())),
+ );
+
+ $element['omega_libraries'] = array(
+ '#type' => 'container',
+ '#tree' => TRUE,
+ );
+
+ $libraries = omega_theme_get_setting('omega_libraries', array());
+ foreach (omega_theme_libraries_info() as $library => $info) {
+ $key = strtolower($info['package']);
+ if (!isset($element['omega_libraries'][$key])) {
+ $element['omega_libraries'][$key] = array(
+ '#type' => 'fieldset',
+ '#title' => t(filter_xss_admin(ucfirst($info['package']))),
+ );
+ }
+
+ $element['omega_libraries'][$key][$library]['status'] = array(
+ '#type' => 'checkbox',
+ '#title' => !isset($info['vendor']) ? $info['name'] : (isset($info['vendor url']) ? t('@library by @vendor', array('@library' => $info['name'], '!url' => $info['vendor url'], '@vendor' => $info['vendor'])) : t('@library by @vendor', array('@library' => $info['name'], '@vendor' => $info['vendor']))),
+ '#description' => $info['description'],
+ '#default_value' => !empty($libraries[$library]['status']),
+ '#parents' => array('omega_libraries', $library, 'status'),
+ );
+
+ if ($missing = omega_extension_assets_check_library($info)) {
+ foreach ($missing as &$file) {
+ $path = drupal_get_path('theme', $form_state['build_info']['args'][0]);
+ $file = strpos($file, $path) === 0 ? substr($file, strlen($path) + 1) : $file;
+ }
+
+ $element['omega_libraries'][$key][$library]['missing'] = array(
+ '#theme' => 'item_list',
+ '#title' => t('Missing files'),
+ '#items' => $missing,
+ '#prefix' => '>subject; ?>
+
+
+
diff -r d72257b2ddc2 -r a75ead649730 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:18:21 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 d72257b2ddc2 -r a75ead649730 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:18:21 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
+ */
+?>
+
+
+
+
+
diff -r d72257b2ddc2 -r a75ead649730 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:18:21 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
+ */
+?>
+
+
+
+
+
+ $title): ?>
+
+
+
+
+
+
+
+ $data): ?>
+
+
+
+
+
+
+
+block_title; ?>
+ region_select; ?>
+ weight_select; ?>
+ configure_link; ?>
+ delete_link; ?>
+ >subject; ?>
+
+
+ >
+
+
+
+
+
+
+ >
+
+
+>
+
+
+
+
+
+
+
diff -r d72257b2ddc2 -r a75ead649730 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:18:21 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
+ */
+?>
+
+
+
+
+ $forum): ?>
+
+
+
+
+
+
+
+
+is_container ? 'colspan="4" class="forum-topic__details forum-topic--container"' : 'class="forum-topic__details forum-topic--forum"'; ?>>
+ ', $forum->depth); ?>
+
+
+
+ description): ?>
+
+
+ is_container): ?>
+
+
+
+ num_topics ?>
+ new_topics): ?>
+
+
+
+ new_text; ?>
+
+ num_posts ?>
+
+ last_reply ?>
+
+
+
+
+
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/templates/forum/forums.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/forum/forums.tpl.php Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+icon; ?>
+
+
+ moved): ?>
+ message; ?>
+
+
+ comment_count; ?>
+ new_replies): ?>
+
+
+ new_text; ?>
+
+ last_reply; ?>
+
+ >
+
+
+ >
+
+
+ >
+
+
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/templates/views/views-view-list.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/views/views-view-list.tpl.php Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ $row): ?>
+ >
+ $item): ?>
+
+
+
+>
+
+
+
+ >
+
+
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/templates/views/views-view-unformatted.tpl.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/templates/views/views-view-unformatted.tpl.php Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,15 @@
+
+
+
+
+ $row): ?>
+
+ $label): ?>
+
+
+
+
+ $row): ?>
+ >
+
+
+
+ >
+ $content): ?>
+
+
+
+>
+
+
+
+
',
+ '#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 d72257b2ddc2 -r a75ead649730 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:18:21 2013 +0100
@@ -0,0 +1,39 @@
+';
+ if (!empty($block['title'])) {
+ $output .= '' . $block['title'] . '
';
+ }
+ if (!empty($block['content'])) {
+ $output .= '';
+ $variables['primary']['#suffix'] = '
';
+ $output .= drupal_render($variables['primary']);
+ }
+ if (!empty($variables['secondary'])) {
+ $variables['secondary']['#prefix'] = '' . t('Secondary tabs') . '
';
+ $variables['secondary']['#prefix'] .= '';
+ $variables['secondary']['#suffix'] = '
';
+ $output .= drupal_render($variables['secondary']);
+ }
+
+ return $output;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/theme/more-help-link.theme.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/theme/more-help-link.theme.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,12 @@
+ array('class' => array('more-link'))));
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/theme/pager.theme.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/theme/pager.theme.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,128 @@
+ $pager_max) {
+ // Adjust "center" if at end of query.
+ $i = $i + ($pager_max - $pager_last);
+ $pager_last = $pager_max;
+ }
+ if ($i <= 0) {
+ // Adjust "center" if at start of query.
+ $pager_last = $pager_last + (1 - $i);
+ $i = 1;
+ }
+ // End of generation loop preparation.
+
+ $li_first = theme('pager_first', array('text' => (isset($tags[0]) ? $tags[0] : t('« first')), 'element' => $element, 'parameters' => $parameters));
+ $li_previous = theme('pager_previous', array('text' => (isset($tags[1]) ? $tags[1] : t('‹ previous')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
+ $li_next = theme('pager_next', array('text' => (isset($tags[3]) ? $tags[3] : t('next ›')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
+ $li_last = theme('pager_last', array('text' => (isset($tags[4]) ? $tags[4] : t('last »')), 'element' => $element, 'parameters' => $parameters));
+
+ if ($pager_total[$element] > 1) {
+ if ($li_first) {
+ $items[] = array(
+ 'class' => array('pager__item', 'pager__item--first'),
+ 'data' => $li_first,
+ );
+ }
+ if ($li_previous) {
+ $items[] = array(
+ 'class' => array('pager__item', 'pager__item--previous'),
+ 'data' => $li_previous,
+ );
+ }
+
+ // When there is more than one page, create the pager list.
+ if ($i != $pager_max) {
+ if ($i > 1) {
+ $items[] = array(
+ 'class' => array('pager__item', 'pager__item--ellipsis'),
+ 'data' => '…',
+ );
+ }
+ // Now generate the actual pager piece.
+ for (; $i <= $pager_last && $i <= $pager_max; $i++) {
+ if ($i < $pager_current) {
+ $items[] = array(
+ 'class' => array('pager__item'),
+ 'data' => theme('pager_previous', array('text' => $i, 'element' => $element, 'interval' => ($pager_current - $i), 'parameters' => $parameters)),
+ );
+ }
+ if ($i == $pager_current) {
+ $items[] = array(
+ 'class' => array('pager__item', 'pager__item--current'),
+ 'data' => $i,
+ );
+ }
+ if ($i > $pager_current) {
+ $items[] = array(
+ 'class' => array('pager__item'),
+ 'data' => theme('pager_next', array('text' => $i, 'element' => $element, 'interval' => ($i - $pager_current), 'parameters' => $parameters)),
+ );
+ }
+ }
+ if ($i < $pager_max) {
+ $items[] = array(
+ 'class' => array('pager__item', 'pager__item--ellipsis'),
+ 'data' => '…',
+ );
+ }
+ }
+ // End generation.
+ if ($li_next) {
+ $items[] = array(
+ 'class' => array('pager__item', 'pager__item--next'),
+ 'data' => $li_next,
+ );
+ }
+ if ($li_last) {
+ $items[] = array(
+ 'class' => array('pager__item', 'pager__item--last'),
+ 'data' => $li_last,
+ );
+ }
+ return '' . t('Pages') . '
' . theme('item_list', array(
+ 'items' => $items,
+ 'attributes' => array('class' => array('pager')),
+ ));
+ }
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/theme/panels-default-style-render-region.theme.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/theme/panels-default-style-render-region.theme.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,8 @@
+ array(
+ array('class' => array('choice-flag')),
+ drupal_render($form[$key]['chtext']),
+ ),
+ 'class' => array('draggable'),
+ );
+ if ($is_admin) {
+ $row['data'][] = drupal_render($form[$key]['chvotes']);
+ }
+ $row['data'][] = drupal_render($form[$key]['weight']);
+
+ // Add any additional classes set on the row.
+ if (!empty($form[$key]['#attributes']['class'])) {
+ $row['class'] = array_merge($row['class'], $form[$key]['#attributes']['class']);
+ }
+
+ $rows[] = $row;
+ }
+
+ $output = theme('table', array('header' => $headers, 'rows' => $rows, 'attributes' => array('id' => 'poll-choice-table', 'class' => array('poll-choice-table'))));
+ $output .= drupal_render_children($form);
+ return $output;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/theme/status-messages.theme.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/theme/status-messages.theme.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,43 @@
+ t('Status message'),
+ 'error' => t('Error message'),
+ 'warning' => t('Warning message'),
+ );
+ foreach (drupal_get_messages($display) as $type => $messages) {
+ $output .= ' ';
+ }
+
+ return $output;
+}
diff -r d72257b2ddc2 -r a75ead649730 sites/all/themes/omega/omega/theme/system-themes-page.theme.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/themes/omega/omega/theme/system-themes-page.theme.inc Fri Sep 20 11:18:21 2013 +0100
@@ -0,0 +1,67 @@
+';
+
+ foreach ($variables['theme_group_titles'] as $state => $title) {
+ if (!count($theme_groups[$state])) {
+ // Skip this group of themes if no theme is there.
+ continue;
+ }
+ // Start new theme group.
+ $output .= ''. $title .'
';
+
+ foreach ($theme_groups[$state] as $theme) {
+ // Theme the screenshot.
+ if($theme->screenshot) {
+ $theme->screenshot['attributes']['class'] = str_replace('screenshot', 'theme-selector__screenshot', $theme->screenshot['attributes']['class']);
+ $screenshot = theme('image', $theme->screenshot);
+ } else {
+ $screenshot = '' . $theme->info['name'] . ' ' . (isset($theme->info['version']) ? $theme->info['version'] : '') . $notes . '