diff --git a/drupal/sites/default/boinc/modules/contrib/cck/CHANGELOG.txt b/drupal/sites/default/boinc/modules/contrib/cck/CHANGELOG.txt new file mode 100644 index 0000000000000000000000000000000000000000..5a1a7910499990c1ec9ca695eac20722f4de73d9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/CHANGELOG.txt @@ -0,0 +1,624 @@ +//$Id$ + +CCK 6.x-2.10 +============ + +Security: Open Redirect - SA-CONTRIB-2015-126 + +CCK 6.x-2.9 +=========== + +Features +- #932680 by Dave Reid: Token integration - allow using of Token API's new $options param +- #1008184 by merlinofchaos, bojanz, dereine, yched: Adapt to Views 3 "semantic views" feature (backwards compatible with Views 2) + +Bugfixes: +- #863226 by KarenS: make sure we have a function that will return inactive instances when other instances of the same field are still active. +- #887742 by yched: fix notices in _content_get_formatter() in some Views +- #736440 by yched, dhthwy: fix memory leaks on long running migration scripts (e.g. migrate.module) +- #705512 by cha0s, roderick: 'add more' button - fix PHP 5.3 compatibility +- #894880 by yched: fix notices in check_plain() when rendering empty 'plain text' values +- #728472 by Darren Oh: Ensure the module's preprocess functions run first +- #986612 by Dave Reid: Token integration - fix variable name clash (harmless in normal cases) +- #435520 by yched, sun: Fix text fields rendered as 'n/a' in some cases +- #739490 by foripepe: Token integration - fix notices during token generation + +CCK 6.x-2.8 +=========== + +Bugfixes: +- SA-CONTRIB-2010-088 follow up fix for nodereference_autocomplete_access() and content_access(). + +CCK 6.x-2.7 +=========== + +Features: +- #692822 by Dave Reid, add authoring info and publishing options to CCK extra fields. +- #670344 by dagmar: Make CCK compatible with both, views 2 and views 3. + +Bugfixes: +- #470470 by neilnz, use iLIKE for postgres selects. +- #769592 by vkareh, add default values to nodeapi. +- #714762 by Robbert, make diff module integration PHP5 compliant. +- Add db_rewrite_sql() check to nodereference formatters. +- #625768 CCK 6.x-2.6, got fatal error on update.php while running userreference_update_6002(). +- #649106 by thekevinday: Fix content_copy_form_alter(), where $form_state argument is not passed by reference. +- #446390 by mani.atico and fago: improve rules condition to be more robust when checking for empty values. + +CCK 6.x-2.6 +=========== + +Please visit update.php apply pending updates after uploading the new files. + +This release: +- The main reason to pack this release is to keep CCK in sync with recent changes in Views 2.7 that broke the advanced views feature in Node reference fields. + +Features: +- #244896 by stella, canaryMason - Add incremental classes for multiple value fields in views. +- #227129 by igor.ro - Expose "delta" column in multiple value fields to Views. +- #531662 by neochief - i18n support. Allow external modules to translate field labels, descriptions and allowed values list as typed in the field settings form. +- #531662 i18n support for fieldgroups. +- #558420 Accept trimmed titles in nodereference autocomplete validation to prevent title mismatch errors when title ends with space. +- #596428 by NancyDru - Allow external modules alter the content type list. + +Bugfixes: +- #416134 Userreference, impossible to filter allowed values by blocked users. Requires update.php. +- #545942 warning: array_filter() [function.array-filter]: The first argument should be an array in userreference_update_6002(). +- #521002 Fix validation errors when using optgroups in allowed values for select elements. +- #550252 by GuyPaddock - content_db_index_exists produces SQL errors when creating node reference fields for MySQL 4 (related to #231453). +- #551280 by xurizaemon - Typo fix for "this field cannot hold more that 3 values" error message. +- #558744 by chellomere - Fix one of the swedish translation strings to be correct, and much clearer. +- #562260 by przadka - content_db_index_exists() has wrong syntax for PostgreSQL. +- #567168 by jcmarco - Checkbox required not defined for on/off widgets. +- #568430 by Jody Lynn - Bad @see in content-field.tpl.php. +- #572672 by Jan van Diepen - Remove redundant (and bad) inclusion of node/content_types.inc in content_copy_import_form_submit(). +- #585048 Setting "All users" in "User status that can be referenced" option reverts to "Blocked users". +- #589306 warning: Invalid argument supplied for foreach() in includes/panels/content_types/content_field.inc on line 166. +- #605152 by pokurek - Missing number formatter fr_2. +- #604830 by mattyoung - 32 characters limit on field and group identifiers in "Manage fields" screen. +- #464030 by eojthebrave - Typo in content_copy.module help. +- #614292 by DeFr - Fix CCK Reference fields based on views broken by recent change in views_plugin_style Views 2.7 (#502348). + +CCK 6.x-2.5 +=========== + +A few files have been added and/or removed in this package. It is recommended to replace the whole CCK directory with the new one. +Please visit update.php apply pending updates after installing the new files. +It also worths to mention that Panels 3 integration has been reviewed and enhanced with display options for fiels and field groups. +IMPORTANT: All sites using Diff module with CCK for Drupal 6 are strongly encouraged to upgrade to CCK 2.5 (see #538872 below). + +Features: +- #428650 Conditional cache/menu rebuild for content CRUD methods. +- #334945 Save default values when field is hidden because of access permissions. +- #503258 by eaton: allow 'extra fields' to provide 'configure' and 'remove' links. +- #505278 Panels 3 and multiple node type fields. +- #495582 Reviewed Panels 3 integration (prep work for combo / multigroups). + Implementation of fieldgroup_view_group() that can be used to render field groups. +- #417122 by quicksketch: allow drupal_alter on field and widget settings. +- #514452 Add new argument $node to content_access() to enhance the context for hook_field_access(). +- #523072 by merlinofchaos - Have nodereference relationships limit CCK field availability as well. +- #519870 by joachim - Add a note to say offset starts from 0 in grouping options for views handler for multiple values fields. +- #231453 Allow fields index their columns. Implemented for reference value column in node and user reference fields. Needs update.php. +- #521002 by mh86 - Support for optgroups in allowed values for select elements. + +Bugfixes: +- #499696 by DeFr - Noderefernce / Userreference: fix Views mode when the view has exposed filters. +- #498924 #multiple FAPI attribute is used for a radios and checkboxes in content export forms. +- #409144 Review extra elements for node edit form provided by core modules. +- #361473 CCK fieldgroup panels doesn't respect CCK field privacy settings. +- #515984 Multiple field delta ORDER BY incorrect. +- #414298 by Michelle, merlinofchaos - Follow up to remove fieldgroup.panels.inc (it was moved to panels/content_types). +- #522112 by hefox, prevent malformed condition for vid IN () in views handler for multiple values fields. +- #505278 by Michelle, merlinofchaos - Provide backward compatibility with previous method to build Panels 3 subtype names for fields. +- #523864 Minor coding style issues in Panels 3 relationships implementations. +- #481568 by merlinofchaos - Empty property error when attempting to save a user reference in Panels. +- #510396 by yched - Use field/type definition to render fields in views. +- #393020 by auth - Fieldgroup data is lost when importing to module provided content type with group info for existing fields. +- #538872 Diff does not respect field permissions. + +CCK 6.x-2.4 +=========== + +Hotfix release for 2.3: +- #482774 Update breaks when CCK is disabled. + +CCK 6.x-2.3 +=========== + +Please visit update.php apply pending updates after uploading the new files. + +This release: +- fixes a few bugs, +- adss initial Panels 3 support (Panels 2 not supported), +- removes the unfinished Multigroup feature (work on this will continue in an experimental branch) + +Features: +- #414298 by Michelle, merlinofchaos - Add Panels 3 integration for fields and fieldgroups. +- #419678 Views integration: expose CCK fields to 'Node revision' Views. +- #399778 by Benjamin Melençon - Nodereference / Userreference: Add 'size' setting to autocomplete widgets. +- #479044 by merlinofchaos - Add Panels 3 relatioships for nodereference and userreference fields. + +Bugfixes: +- #407446 by quicksketch: prevent double serialization during per-field to per-type migration. + Followup: update function to fix potentially existing corrupted data. +- #407344 fix html appearing in selects in Views filters. +- #409320 by bengtan: Nodereference / Userreference - fix 'this post cannot be referenced' for views-defined referenceable nodes/users, when the view definition has a 'limit'. +- #409398 by markus_petrux - fix handling of fieldgroup_types() (prep work for combo / multigroups) +- #356908 Number : Correclty filter 'prefix' and 'suffix' properties. +- #412058 by fago - Rules integration: Fixed condition 'field has value' when operating on viewed nodes. +- #413792 Views integration: fix fields using 'multiple formatters' and not 'group multiple fields'. Thanks Crell and quicksketch for the detective work. +- #421126 Views integration: Use value aliases in argument title replacements for text / number fields. +- #397358 by Darren Oh, yched, markus_petrux - Views integration: Use node title / user name in argument title replacements for nodereference and userreference argument fields. +- #428400 Views integration: Fix fatal error with Views 2.4 (views_handler_filter_float has moved). Preserved compatibility with Views 2.3. +- #447562 by markus_petrux: fix non-XHTML markup on 'Manage fields' screen. +- #369364 Views integration: fix non-XHTML markup when displaying fields with the 'group multiple values' option. +- #441412 by jcnventura - Add 'Print' display context on 'Display fields' pages when book.module is enabled. +- #458952 Let different modules defined the same build_mode information. +- #383038 by markDrupal - Userreference: fix broken 'reverse links' with fields in per-type table. +- #479074 by rickward: prevent minor XSS vulnerability when displaying user-submitted 'Body field' labels. +- #479994 by quicksketch: fix "add more' button with devel.module's query logging. + +CCK 6.x-2.2 +=========== + +IMPORTANT: +This release fixes a security issue (XSS vulnerability) in nodereference and userreference modules. +All sites are using CCK for Drupal 6 are strongly encouraged to upgrade to CCK 2.2. +Note that the Drupal 5 versions are not affected. +See the Security Annoucement on http://drupal.org/node/406520 for more informations. + + +Features: +- #361311 Add poll settings forms to Manage fields screen. +- Add book form to Manage fields screen. +- #131953 by markus_petrux - Views integration: expose additional db columns. +- #349987 by Michelle - Panels integration for fieldgroups. +- #362216 by markus_petrux - sort the admin/content/types/fields overview by field name. +- #242583 by jmiccolis - Number: Push maximum 'scale' setting up to 10 for decimal fields. +- Correct RTL display. +- #405452 - Views integration: Update to Views 2.3 API ('link to node'), with 2.2 compatibility preserved. + +Bugfixes: +- #392476 Make sure CCK textarea fields in a View don't have a span wrapped around a block-level element. +- Fix devel_generate for decimal and float values. +- #358700 Can't use array_slice() on assoc array in PHP4. +- #196421 Prefixed tables weren't getting queried correctly. +- Don't assume display_settings[$context] always exists, newly enabled modules may add new contexts that weren't there when the field was last edited. +- #339537 by markus_petrux: fix orphan fields in {content_group_fields} table when fields are removed. +- Views integration: use shorter titles in Views admin summaries (see http://drupal.org/node/326034). +- #334290 by drewish - Userreference: user names not displayed in Views summaries. +- #343138 by duellj - Fix tokens for empty noderef / userref fields. +- #343306 Validate text 'max length' to be a positive integer +- #344004 by markus_petrux - Diff integration : fix error on non-'core CCK' field types. +- Diff integration: limit the number of additional queries for noderef/userref. +- Diff integration: refactored around a new hook_content_diff_values() to save contrib field modules the +burden of implementing hook_diff. For most field types, the default content_field_content_diff_values() +should be enough, though. +- #344216 by dbabbage: Fix incorrect url to Schema module in tests descriptions. +- #336174 Move actual field access check in content.module, with content_permission.module providing one permission-based implementation. +- #336174 (followup) Make sure content_view_field() and content_format() both respect field access rules. +- #351929 by lyricnz - Views integration: make sure formatters get a pseudo-node with enough info. +- #355712 by fractile81 - Fieldgroup: fix extraneous cache clears. +- #356666 by flobruit - fix 'exclude' display setting wrongly set across shared instances of a field. +- Fix 'undefined variable' notice when submitting field settings form with 'php code for default value. +- #353012 User reference - fix duplicate 'reverse links' on user profile pages when the same user is referenced by several userref fields in a node. Also improves performance. +- #342427 Views integration - fix summaries for nodereference and userreference fields. +- #363456 by dww - Fix some cases of bogus d-n-d reordering of 'pseudo-fields'. +- #366935 by drewish - Make the 'Views mode' feature in noderef / ueserref visible even if no usable View exists yet. +- #371306 fix duplicate HTML when using the JS-'add more' button. +- #370004 by dopry - Fix JS-'add more' button breaking fielfield's AHAH upload. +- #374213 by rpanna - Fieldgroup: All field instances removed their groups when one instance is deleted from a content type. +- #356158 by markus_petrux - Fix more (hopefully all ?) cases of bogus d-n-d reordering of 'pseudo-fields'. +- #381876 by DamienMcKenna - Content Copy: Fix formatting glitch in exported type definitions. +- #346202 Fieldgroup: let the 'simple' template be overridable (thks fiskit) + allow template variants. +- #382004 by elcuco - Field name and group name fields should stay LTR for RTL languages. +- #360712 by tombigel - CSS tweaks for RTL languages. +- #375316 Nodereference/Userreference: Ensure allowed values always return at least an empty array. +- #368155 Nodereference/Userreference: Fix performance issue on large sites when validating empty noderef/userref fields. +- #319778 Optionwidgets: Fix double encoding issues for &, >, <,... chars in select lists. + +CCK 6.x-2.1 +=========== + +This release fixes two critical issues: +- #331293 by Timo.Kissing - Content copy: no fields proposed for export (#320632 followup). +- #331033 Views integration: Fix fatal error in content_handler_field.inc in some circumstances. + +Other fixes: +- #331179 Userreference: 'reverse link' checkbox stayed unchecked. +- Uninstall forgot to remove some variables. +- #331794 Fix false positives for "The default value is invalid" error message. +- #331995 Fix 'invalid argument for foreach' warning on nodes with inexistent type. +- Views integration: make sure our own render_link doesn't output empty links (see #332679). + +CCK 6.x-2.0 +=========== + +IMPORTANT : this release fixes (minor) cross-site scripting (XSS) vulnerabilities +in nodereference.module, userreference.module, content_copy.module, and CCK's Views integration +See the Security Annoucement on http://drupal.org/node/330546 for more information. + +Note: Filters available for CCK fields in Views have changed slightly since the RC releases. +If upgrading from a RC release, you might need to check your views, and if needed. +This only applies to filters defined on Text or Number fields that specify a list of 'Allowed values'. +Filters on other CCK fields are not affected. + +Main new features since RC10: +- #300368 Add option on Display fields screen to omit fields or groups from the $content value passed to the node template. +- #298651 by smk-ka, yched - Nodereference/Userreference: Enhance performance on large sites. + This also adds 'autocomplete mode' widget settings (full string / beginning of string). +- #329447 add content_view_field() API function to display a single field, fully themed with label and multiple values, to be used by 3rd party code. + +Other changes: +- Content_generate should be passing field info and updating $items. +- Fix bug in content_generate that was adding fully formatted textarea values to textfield fields. +- #329037 Fix small bug in content_generate function method of calling fields that handle their own multiple values. +- #324826 Change Advanced help path and topic to use & prefix per latest change in Advanced help. +- #324610 Add Advanced help files for basic fields and hooks so they'll show up in the CCK advanced help documentation. Intended to be used as examples by other field modules for a way to add more field documentation. +- #321024 Add content_associate_fields() to the content_check_update() function because it can get skipped when updates are aborted or the content module is not yet updated. +- Fix bad logic in testing content version variable to prevent warning messages before content module is updated. +- Get rid of t() around Views field label since Views already has it marked as a translatable option. +- #285470 by jhuckabee, store field label in the view in all cases, previously only custom labels were stored. +- #266309 by abbasmousavi, change silent fix to error message for invalid input into number fields. +- #318224 by brmassa, error in Content Copy handling of fieldgroups. +- #198508 Add messages to Manage fields screen about inactive fields. +- #320743 Revert group names uniqueness rules as per D5 behavior (group names unique only inside content types). +- #310219 followup : numeric (core) rendering modes were not preserved in some cases. +- Fix 'unknown index' warnings on fieldgroups settings pages. +- #320139 by Moonshine - Noderef / Userref: Fix single-quotes encoding in 'Views' mode with option widgets. +- #318143 by Douggreen - Panels integration: make widget label translatable. +- #321147 Views integration: float/decimal filters round values to integers. +- #321702 Views integration: fix rendering of multiple-values formatters. +- #322917 Upgrade path: Missing information text on update 6000 when content.module not enabled. +- Replaced theming instructions in theme/README.txt with advanced_help pages. +- #323436 by hass: fix a few strings + translation bugs. +- #323745 by robertgarrigos: Fix performance issue when submitting 'display fields' form. +- #316292 by fractile81: Turn potentially time-consuming updates into multi-pass updates. +- Remove unwanted 'N/A' option on noderef/userref fields using checkboxes. +- #319131 by Moonshine - Add 'title-raw' token for noderef fields. +- #324300 Views integration: fix sorting for multiple fields by allowing the sort to act on one specific delta. + Also disable tablesorting for multiple fields with 'group multiple values' option. +- Views integration: fix broken query for fields retrieved through relationships when relation is empty. +- #325262 Fix flawed logic in filtering out empty values. +- #297322 Views integration: display node title / user name for argument summaries with noderef / userref fields. +- #324301 Optionwidgets: check for maximum number of values. +- #320632 Content Copy: Make fields/groups checked for export by default + display the list in an overview table. +- Content Copy: Import / export weights of dnd-enabled non-CCK fields. +- #327715 Babysit 'invalid foreach' warnings caused by invalid incoming $node objects. +- #328763 Adjust weight of non-cck fields even if there are no CCK fields for the content type. +- Views integration: fixed a few non-relationship safe areas. +- Views integration: fix 'link this field to its node'+'group multiple'+relationships. +- #323681 Panels integration: make 'field as pane' work again. +- #311912 Views integration: The many_to_one filters for fields with 'allowed values' gain should not replace the regular 'starts with'/'greater than' filters. + +CCK 6.x-2.0-rc10 +================ + +- Get rid of helper function content_is_updated(), we can do it better using the content version variable. +- #318224 by brmassa, fix several errors in Content Copy. +- #318387 Make sure old fieldgroup updates don't run if tables were never created. +- #318227 Clean up update abort logic to more clearly explain what still needs to be done, add a helper function to prevent dangerous database operations until database is updated. +- #317232 Change css file name from content.css to content-module.css to avoid namespace collisions. +- #316656 Default weight must be zero, not NULL, or form ordering will be incorrect. +- #107407 by dopry, optimization patch, do nothing in hook_form_alter() and hook_nodeapi() if there are no fields. +- #317932 Fix userreference documentation typo. + +CCK 6.x-2.0-rc9 +=============== + +- Change update instructions to recommend leaving CCK modules out of the modules folder until they're enabled. +- #317036 by hass, context-sensitive translation fixes. +- #316354 by fago, hass, fix translation issues in rules.inc files. +- #312546 by stella, code cleanup. +- #311146 by Brian294, dheffron, yched, and others, fix critical javascript problem in new Manage fields UI screen in some themes. +- #317032 by hass, code cleanup. + +CCK 6.x-2.0-rc8 +=============== + +Be sure to visit update.php after uploading this release. + +- #314986 by moshe weitzman, remove hook_devel_caches(), deprecated in favor of content_flush_caches(). +- Clean up inconsistencies in unsetting _error_element, sometimes not unsetting it, sometimes not testing before unsetting it causing undefined index errors. +- Add more documentation of how nested nodereference and userreference items work. +- #119102 Combo field prep, Use === in userreference and nodereference validation to be sure we get right results if parent is a zero (delta) value instead of a string name. +- #119102, #314843 Make sure module process code doesn't override #element_validate set by other modules. +- #119102 Combo field prep, rework fieldgroup name validation into API to be used by other modules. +- #312546 by stella - Change some links to make translation easier. +- Added the #delta value to the wrong place in the element, it was inaccessible to the formatter theme. +- #119102 Combo field prep, rework the field overview form so it can hanle other kinds of groups. +- #119102 Combo field prep, add hooks to the fieldgroup module so other modules can alter group info. +- #119102 Combo field prep, add group_type information to the Manage fields screen. +- #119102 Combo field prep, add group_type column to content_group table. +- #310420 Make sure fields created by disabled modules get marked inactive in the database. +- #119102 Combo field prep, allow way to override multiple values settings for optionwidgets. +- #119102 Combo field prep, add prev_parent and group info to display fields overview. +- #119102 Combo field prep, add a helper function that can determine if a field is in use and the max delta value in use. +- #309667 Add Panels integration in. This is still experimental since Panels for D6 is still experimental. +- #307909 Don't create Views tables for fields that don't create db columns. +- Make incompatibility with older Views releases stand out more. +- Fix errors when rendering fieldgroups in 'advanced' contexts (RSS, search...). +- Do not insert field and group labels in search index. +- Fix drag-n-drop order lost when node form is redisplayed after node preview or failed validation. +- Fix drag-n-drop order not accounted for in node previews. +- #306572 Number: Incorrect validation of allowed values for Float and Decimal fields. +- #306963 by p.brouwers - Number : fix missing formatter for '9.999,99' (be_2). +- Views integration : Add default label for userref and noderef relationships. +- #234774 Nifty new UI to add fields and groups (requires a cache clear) + initial integration with advanced_help module. +- #281749 by asimmonds: fix '0' not parsed as an alias for allowed values. +- #309365 Views integration: Consider relationships when force-adding the 'Node: Type' field - thks jhuckabee. +- #308215 by Reg - Nodereference: Do not filter on empty string when querying for referenceable nodes. +- #308778 Fix $item['view'] element missing for tokens and contemplate. +- #310414 Fix broken redirects when adding fields to content types with an underscore in their machine names. +- #310484 by merlinofchaos - Views integration: Allow relationships to work nicely with multiple values. +- Views integration: reorder elements in the field's settings to ba a little more logical. +- #306604 Views integration: fix relationships with 'group multiple values' option. Thx merlinofchaos for the help. +- Add a message on the 'Manage fields' screen about the benefits of advanced_help module. +- #311883 by hass : Fix a string to give translators better context. +- #310873 Upgrade path : abort updates if content.module and/or field modules are disabled, and fix existing sites possibly affected. +- #310219 Let modules expose additional display modes iunder the 'Display fields' tab : hook_content_build_modes(). + +CCK 6.x-2.0-rc7 +=============== + +Note: +- There has been a few files moved around since RC6, so be sure to *delete* the previous contents +of your cck/ folder before uploading the new files, in order to avoid duplicates. +- The admin forms (field creation, field edition...) have been renamed to comply with usual form +naming conventions. Modules and custom code that rely on those form ids through hook_form_alter() or +drupal_execute() will need to be updated. +- The final 6.x-2.0 release is currently targetted for the second half of September. + +Main bugs fixed since RC6: +- Content Copy: Fix multiple bugs when importing/exporting content types : +exporting field definition can alter the actual field's settings +'this post cannot be referenced' error when exporting nodereference fields +no export of default values +- #198502 D5 upgrade path: Prevent field module upgrades from running before content.module upgrades. +- #293698 Views integration: make 'show n values starting from m' actually work. +- #292872 Data loss issue: fields and field data deleted for content types defined by disabled modules. +IMPORTANT: Since disabling all contrib modules is a recommended step prior to upgrading a D5 site to D6, +it is highly advised that D5 sites using CCK are updated to CCK 5.x-1.8 (which contains the same fix) +before starting the D6 upgrade process. + +Main new features since RC6: +- Updated to latest Views 2 API. Views integration requires Views 6.x-2.x-dev newer than Sep 3, 2008. +- #295556 by CPyle - Userreference: let referenceable users be defined by a View. +- Userreference: Add 'Radios / checkboxes' widget. +- #294797 New $FIELD_NAME_rendered and $GROUP_NAME_rendered variables for node.tpl.php. +- Nodereference: Allow specific node templates for nodes displayed as values of a noderef field. +- #301736 by nedjo - Nodereference: Multilingual support; if available, propose translations of referenced nodes when creating a new translation. +- #196468 by Nedjo - Content copy: Provide a link to automatically import a file into Content Copy. + +Other changes: +- Avoid undefined index error in Content Copy when fieldgroup is enabled but there are no groups. +- #296077 Add delta to formatter information. +- #128038 Alter _content_admin_form() to provide the raw widget default values as well as the default value widget so programmed forms will have those values available. You can't tell when you construct the form if it's a programmed form or not, so we will always have to create the default value widget, but we don't always have to use it. This will also get the default values into the Content Copy export in a way that Content Copy import can pick them up, and alter validation to unset the default value widget and skip the default value widget processing if it's a programmed form. Since we are now provided the actual default value (not just the default value widget) in the export, we can safely pick it up in the import. +- #128038 Use content_field_instance_collapse() to send form values in the Content Copy export to be sure we get the original field values for checkboxes instead of the true/false values we will get otherwise. +- #300108 Add group value back to field settings form so it will appear in the Content Copy export. +- #283985 Force Content Copy export to use current field values to avoid storing mangled data back to field. +- #298440 by Moonshine and KarenS: move form permission checking to content_field_form() and don't call hook_widget for users w/out permission. +- #294726 by profix898 and yched: _content_type_info() does not reset on content type changes. +- #293273 Nodereference: update 'referenceable types' when type name changes. +- #295914 Fix additional problems when installing CCK in install profiles. +- #295664 Views integration: let summaries display 'allowed values' aliases if any. +- Views integration: prevent empty links for the 'no value' items in summaries. +- #296748 Text: Fix PHP warning when $node->build_mode not set. +- #297915 Fix content_copy. +- #298674 Content copy doesn't import all type properties. +- #293471 Remove fieldgroup selection on field settings form. +- Userref / Noderef : Add a 'none' choice for non-required, single fields with 'Radios / checkboxes' widget. +- #298823 Views integration: do not step into views_* namespace. +- #299698 Userreference: autocompletion query when typed string is '0'. +- #300236 Fix inconsistent schema for 'locked' column between install and updates. +- Do not display 'label' settings on 'advanced' subtab of 'Display fields'. +- #266205 by sun: add zebra classes for field items. +- #299870 Incorrect handling of custom weight for 'Language' node form element. +- Fieldgroups: display options were not supported for 'advanced' contexts (RSS, search index...). +- Fieldgroups: do not display group label when building the search index. +- Fieldgroups: Remove tinyint (127) limitation on group weights. +- #301984 by joetsuihk - Views Integration: do not display empty divs on empty fields. +- Views integration : prevent possible 'invalid argument for foreach' warnings with 'group multiple values'. +- Fix tests to work with simpletest 2.x. +- #296301 by Moonshine - Fieldgroups: fix call_user_func_array() error on add / configure / remove pages. +- #118364 Number (decimal): fix unneeded information message when using comma as a separator ("150,00 was changed to 150.00"). +- Fieldgroup: New groups are not styled on node view until 'display fields' form is submitted. +- #303664 Views integration: update to new Views API for handler / plugins. +- #303475 by wrunt - Optionwidgets : unchecked 'single on/off checkbox' stores 0/'0' instead of the 'off' value. +- #304450 Userreference - fix broken autocomplete for 'simple' mode / fix broken 'advanced - views' mode after Views API changes. +- Fix PHP warnings on node display for hidden fields inside fieldgroups. +- #305048 by asimmonds: fix incorrect link on 'start update' page when updates were aborted. +- Content copy: Fix broken group export as a result of #296301. +- #304828 Clean up function names in content.admin.inc. +- #285557 Added 'img' to the list of allowed tags in fields descriptions. +- Content copy: wrong page title after export code has been generated. +- Fieldgroup: fix broken node preview. + +CCK 6.x-2.0-rc6 +=============== + +Hotfix release for: +- #295537 fix warnings in update 6004 when site has no actual cck fields. +Those errors were harmless, no need to worry or run update.php again if you had them. + +Minor fix: +- #265795 by smk-ka: formatter labels go through t() twice in Views exposed data. + +CCK 6.x-2.0-rc5 +=============== + +Main bugs fixed : +- #281388 Optionwidgets: Unselect values doesn't take. +- #286457 Fix menu not being always rebuilt when needed. +- #285138 by quicksketch and yched: Allow CCK to be installed in install profiles. + +Main new features : +- #282183 by chx: Nodereference - 'Checkboxes/radios' widget. +- #289138 by dopry: Add support for 'locked' fields (for module-defined fields). + +Other changes : +- #273502 Add descriptions to the non-CCK form elements on the Manage fields screen. +- Fix PHP warnings when field display is set to 'hidden' and field is in a fieldgroup. +- Re-introduce '<none>' choice for multiselect widgets (optionwidgets, noderef/userref select). +- #281449 Text: maxlength on textfield widget is 128 even when the field has no maximum length. +- Add tests for optionwidgets. +- #282175: Don't mention 'add more' button when the widget opts out of it. +- Optionwidgets: use '- None -' for 'no selection' option (like core's taxonomy.module). +- #286637 by poiu: clearer example for default value with php-code. +- #93436 Add $form parameter to content_validate. +- #277310 by fractile81: update node object by reference in content_load(). +- #285771 Views integration: use the new 'float' filter handler where applicable. +- Fix PHP warnings when renaming a content type. +- #280410 Number: Fix prefix / suffix displayed when field is empty. +- #282937 Fix warnings on uninstall. +- #287540 Add index on nid in data tables, to optimize node deletion (requires update.php) +- #288578 Text: Fix max length to use utf8 length. +- #222214 by aaron, deviantintegral : support tokens for nodererf / userref paths aliases. +- #211306 by asimmonds: Fix error in D5 update with SQL strict mode. +- #292338 by mh89: Set fieldgroup.module's weight to 9 (missing for new D6 installs). +- #292463 Fieldgroup: missing update for fieldgroup table names (didn't actually break anything). +- #292855 by Tgr - Fieldgroup: missing } in query on field instance deletion. +- #292925 by greggles - Text: Fix PHP notice under some circumstances with textarea widget. +- #292675 Support d-n-d reordering of non-cck "fields" for types that have no cck fields. +- #289888 Nodereference: Fix 'full node' and 'teaser' formatters. +- Display field type human names instead of machine names on 'Manage Fields' and 'Fields' overview pages. +- #292884 Better help text for field template suggestions. +- #293163 Use FAPI validation instead of field|widget_settings($op 'validate'). + (the 'validate' op is still supported, though) +- #75423 by mh89 - Text: 'size' setting for textfield widget. + + +CCK 6.x-2.0-rc4 +=============== + +This RC Mainly fixes a critical bug : +http://www.drupal.org/node/277968 - Saving 'Display Fields' wipes widget settings. + +- #278325 Nodereference/Userreference - autocomplete widget does not check nodes/users are 'referenceable'. +- #278325 followup: Unify the mechanism used to assign hook_field('validate') errors to form elements across fields and widgets. +- Userreference - Turn the 'Reverse link' radios into a checkbox in the field settings. +- Nodereference - Only list 'node' Views in the 'advanced mode', and differenciate default views as in D5. +- Optionwidgets - fix PHP warning when creating a new 'on/off checkbox' and no allowed values could be set yet. +- Optionwidgets - fix PHP warning on 'on/off checkbox' only one 'allowed value'. +- Optionwidgets - add a 'warning' message to remind the admins they need to set allowed values. +- #278676 by hass: fix untranslated field and widget type names. +- Do not validate the fields settings form when the 'change label / widget' submits the form. +- #273502 Let the 'menu settings' node-form fieldset on node forms be repositioned. +- #273502 followup: add a description for non-CCK 'fields' on 'Manage fields' tab. +- #278793 by hass: fix untranslated PHP code example. +- Nodereference/Userreference - There were two 'no selection' choices on 'select list' widget for non-required fields. +- #277486 Nodereference/Userreference - no selection with 'select list' widget stores 0 instead of NULL. +- #278789 better wording for the 'PHP default value invalid' error message. +- #267771 orignal patch by quicksketch: Richer label settings for views fields. +- #279204 by eMPee584: fix edit paths inconsistency. +- #276990 Nodereference - error message when no valid node with that title (autocomplete widget). +- Widget (FAPI-)validation messages do not display the field 'label' when the error is on a nth value (n > 1). +- Unify field validation error messages. +- #269319 Reintroduce field template variants; add theme instructions text file. +- #179419 by smk-ka: Content Copy - Import fails when language not English. +- #278899 Nodereference - Refactor 'advanced (Views-defined referenceable nodes)' to use views rendering. +- #279190 content_crud_instance_update wiped existing widget settings in some cases. + Also added a tests for a few basic properties of the CRUD API. + +CCK 6.x-2.0-rc3 +=============== + +- #278116 by Damien Tournoud: Make some strings easier to translate in views intergration forms. +- #278135 fix some translation quirks + fix french typography for ':' :-) +- Nodereference: 'Title mismatch. Please check your selection' error should break validation (+ fix typo). +- #277968 by jpetso: Fix fatal error when cck folder lives in the main /modules folder. + +CCK 6.x-2.0-rc2 +=============== + +- #276994 Follow up, remove conditional loading for content.views.inc, Views handles it. + +CCK 6.x-2.0-rc1 +=============== + +- #276994 Remove views_include_handlers() from content.views.inc, no longer needed. +- Change 'allow_empty' to 'allow empty' so that Views filters work correctly. +- #272871 Pass #node to formatters to be consistent with the values that were available in the D5 version. +- #271294 Add TODO to get rid of content_write_record() once drupal_write_record() is patched. +- #271294 Add documentation for the reason for having a custom version of drupal_write_record. +- Avoid E_All error when prefixes and suffixes are not defined in number module. +- Avoid E_All error, don't try to return $item[0] if there are no items. +- #266590 Make sure a view is valid before trying to use it in the nodereference module to fix upgrade errors when the view has not been updated to Views 2. +- #258127 Get rid of content_menu_needs_rebuild() in remaining places and only rebuild the menu when absolutely needed. +- Alter content_types_install() to make sure it picks up all the regular field and widget values out of the database. Some of the field values were missing, which caused some of the other values to get set incorrectly during updates and when modules are enabled. +- #235063 Fix jumbled multiple values when hitting the 'add-more' button with more than 10 values. + Keep 'add more' button text consistent. +- #270014 by yang_yi_cn: form for multiple values didn't call the right hook_widget +- fix 'Undefined index: #access' notice when content_permissions.module is disabled +- #270315 Mention dependency on schema.module in the desciptions of the CRUD tests. +- #227951 by pwolanin: Add a permission for PHP 'default values' and 'allowed values' +- #271682 by pwolanin: Make simpletests easier by not duplicating field name in same form. +- #270315 by pwolanin: Update simpletest to use DrupalWebTestCase. +- #227951 by pwolanin: Add permission for ability to use php code for default values and allowed values. +- #270827 by pwolanin: Validity checks for the AHAH-'add more' request. +- #271087 Properly handle values '0' for text and number fields. +- #258407 Fix field template name to allow for easy overridability. +- #274038 by jpetso: Fix non-JS mode for 'add more' button. +- #275192 by jpetso: Attach AHAH behaviors to newly inserted widgets on JS 'add more'. +- #271710 by pwolanin: tests for UI field CRUD, and node form generation. +- #266696 by pwolanin: Unable to change the label or widget type for a field. +- #201329 by pwolanin and yched: Fix content_field_instance_delete() not cleaning tables. +- #271577 by pwolanin: Fix unsanitized text (optionwidgets, number, text, field labels, field descriptions) +- #273539 by jpetso: Fix JS-'add more' for complex widgets (e.g. filefield) +- #227435 by pwolanin: Usability - Put fields links on content type overview page +- #277101: Hide fieldset-based fieldgroups when all fields empty +- #198508: Prevent data loss for disabled fields. + +CCK 6.2.beta +============ + +Content Generate (new feature) +- #257874 and #187599 provide a way to auto-generate field content for the devel module. +- #261633 E_All fix for content_generate. + +Usability +- #227439, #227437, #227945 Rework field and widget type handling to simplify the intial screen when choosing a field and widget type by making it a two-step process where you see only the widgets that apply to the field. Move the setting of the field label to the same place where you set the field name. Change the field edit screen to keep it from showing all the different widgets again and instead just display the current widget. Then add a button to change the widget which will take you to another screen to make the change since the rest of the page will need to change when the widget changes. Keep the changes to the widget label in that separate process, too, since that affects the menu tabs that need to be changed before redirecting back to the main page. + +Update processing +- #256141 Add old updates back to fieldgroup.install for situations where the module was briefly enabled and then disabled and never used so the update process doesn't throw an error for the missing updates. +- Fix potential E_All error in userreference after update. +- Fix E_All error that can come up after update if text module is using format column. +- Change the check in _content_type_info to be sure the new 'active' column exists before trying to query the table during installation and updates. Also fix E_All notice for non-existant db_columns during install and update. +- #237585 Try to avoid foreach errors on missing content type information by creating empty arrays in content_info. + +Optionwidgets +- #224391 Get default values working again for optionwidgets. +- #251157 Make sure optionwidgets selections are not lost when previewing node. +- #253038 Make sure empty optionwidget values are always arrays. + +Nodereference +- #264345 Create a nodereference wrapper for setting and rendering a view and store the rendered view in a static variable to ensure the same view is not rendered over and over in the same session. +- #263936 Make sure nodereference select views do not try to use paging and do not limit the items per page. +- Clean up autocomplete handling that uses Views as a selector. +- #262112 Add missing hook_theme definition for the plain formatter. +- #256440 Nodereference was passing wrong object to Views for the Views node selection option. Also need to limit available views to those that have fields defined so we can add the title to the view and so there is something meaningful to display in the select list. + +Views Integration +- #264479 Make sure we don't try to init() a view for fields that don't have one selected. +- #263936 Set arguments in execute_display. Also make sure to pass $string and $exact_string to the view. +- #257566 Move all content fields into a single group in the Views UI. +- #242856 Make sure the node.nid is aliased when creating our grouped fields query so the parent node isn't confused with nodereference's nid column. +- #261528 Add in missing code to create the link to the node if that option is requested. + +Content Copy +- #225664 Make sure groups get imported as well as fields. + +Formatters +- #264768 Make sure handling for all possible states of #single is properly set up. +- #260253 $node->type isn't always set, and if missing the formatters that use $fields($field_name, $type_name) to retrieve the field array end up with an empty value. Add the node type to all content fields views so we can be sure it's available and alter the content_format logic to look for the node type both at $node->type and at $node->node_type, where Views will put it, to properly set the content type. + +General +- #256116 Add a TODO to reconsider handling of CCK data when a content type is deleted. +- Small fix to content_generate to get auto-generation of number values working. +- #265334 Avoid format error messages in the unusual case where you have created CCK content and then delete the content type without deleting the node, since core does not delete the nodes in that case. +- #227256 Add an additional check when creating a new field that the length is no more than 32 characters. +- #260253 When content_type is set but empty, nothing is returned from content_fields(). Fix that by checking for empty() instead of isset(). This is a more general problem that should be fixed in content_fields(). +- #258127 Eliminate need to defer the rebuild of the menu, also adding TODO to see if content_menu_needs_rebuild() can be eliminated. +- #257304 Make sure the widget description is never NULL to avoid problems when a NULL value gets wrapped with t(). +- #259704 Make sure help text always appears. +- #255113 Make sure empty filtered text fields don't pick up unintended values from check_plain(). diff --git a/drupal/sites/default/boinc/modules/contrib/cck/DEVELOPER.txt b/drupal/sites/default/boinc/modules/contrib/cck/DEVELOPER.txt new file mode 100644 index 0000000000000000000000000000000000000000..251d586314679e6ce400ab880bf63e50bccb98f3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/DEVELOPER.txt @@ -0,0 +1,6 @@ +// $Id$ + +DEVELOPER DOCUMENTATION +UPDATING FROM 5.x TO 6.x + +See http://drupal.org/node/191796 for a guide to updating field modules. diff --git a/drupal/sites/default/boinc/modules/contrib/cck/LICENSE.txt b/drupal/sites/default/boinc/modules/contrib/cck/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..d159169d1050894d3ea3b98e1c965c4058208fe1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/drupal/sites/default/boinc/modules/contrib/cck/README.txt b/drupal/sites/default/boinc/modules/contrib/cck/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..edf51ee9e667193c172d98863c2619bbfacb2bb1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/README.txt @@ -0,0 +1,48 @@ +// $Id$ + +Content Construction Kit +------------------------ + +NOTE: Install the advanced_help module (http://drupal.org/project/advanced_help) +to access more help (writing still in progress...) + +To install, place the entire CCK folder into your modules directory. +Go to Administer -> Site building -> Modules and enable the Content module and one or +more field type modules: + +- text.module +- number.module +- userreference.module +- nodereference.module + +Now go to Administer -> Content management -> Content types. Create a new +content type and edit it to add some fields. Then test by creating +a new node of your new type using the Create content menu link. + +The included optionswidget.module provides radio and check box selectors +for the various field types. + +The included fieldgroup.module allows you to group fields together +in fieldsets to help organize them. + +A comprehensive guide to using CCK is available as a CCK Handbook +at http://drupal.org/node/101723. + +Known incompatibilitie +---------------------- + +The Devel Themer module that ships with Devel is known to mess with CCK admin pages. +As a general rule, Devel Themer should only be switched on intermittently when doing +theme work on a specific page, and switched off immediately after that, for it adds +massive processing overhead. + +Maintainers +----------- +The Content Construction Kit was originally developped by: +John Van Dyk +Jonathan Chaffer + +Current maintainers: +Karen Stevenson +Yves Chedemois + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/UPGRADE.txt b/drupal/sites/default/boinc/modules/contrib/cck/UPGRADE.txt new file mode 100644 index 0000000000000000000000000000000000000000..1cb5b61aafff2fc84310306ac74bb8e2ac714717 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/UPGRADE.txt @@ -0,0 +1,87 @@ +// $Id$ + +================================================================ +UPDATING FROM VERSION 4.7 to 6.x +================================================================ + +THERE IS NO DIRECT UPGRADE PATH FROM 4.7 TO 6.x!! FIRST UPGRADE +YOUR DATABASE FROM 4.7 TO THE LATEST 5.x VERSION, THEN UPGRADE +TO 6.x. + +ALWAYS BACKUP YOUR DATABASE BEFORE UPGRADING! + +1) While 4.7 is still installed, upload the latest 4.7 version of + all the CCK files, go to update.php, and run all possible + updates for the Content module and all field modules. + +2) Install Drupal version 5. Once it is running, upload and install + the latest 5.x versions of all CCK modules, go to update.php and + run all possible updates. + +Jump to the instructions for updating from version 5.x to 6.x. + +================================================================ +UPDATING FROM VERSION 5.x to 6.x +================================================================ + +YOU MUST RUN ALL POSSIBLE UPDATES TO YOUR DATABASE IN 5.x USING +THE LATEST 5.x CODE, BEFORE UPGRADING FROM 5.x to 6.x. + +ALWAYS BACKUP YOUR DATABASE BEFORE UPGRADING! + +1) Before upgrading to 6.x, upload the latest 5.x versions of all + CCK modules, go to update.php and run all possible updates. + +2) Disable all CCK modules and remove them from the modules folder + before upgrading. + +3) Install Drupal version 6. Leave all contributed modules out of + the modules folder until core modules are up and running. + Set your administration theme to a core theme like Garland until + everything has been updated to help ensure you don't encounter + theme-related problems accessing the administration area. + +4) Once core is running, upload and install the latest 6.x versions + of ONLY CCK CORE FILES (the ones in the tarball on the CCK + project page). Enable them, then go to update.php and run all + possible updates. DO NOT add any other CCK modules to the + modules folder until the core CCK files are updated and working + correctly. + +5) After updating CCK core modules, you may get messages saying that + some updates failed and that you need to run update.php again. + If you get messages like that, keep re-running update.php until + you get no more messages. + +6) Once the core CCK modules are updated and working correctly, + add other CCK modules to the modules folder, enable them, + and run update.php. For best results, do this one module at a + time so you can tell immediately if any of them create problems + without letting those problems interfere with other updates. + + +Your database should now be ready to run in CCK version 6.x + +================================================================ + +The 4.7 to 5.x steps are necessary because of significant changes +in the database structure between the 4.7 and 6.x versions. These changes +make it extremely difficult to create an automatic upgrade path that +will work reliably in every possible situation. + +The extra steps in the 5.x to 6.x upgrade are because all modules +in the modules folder are automatically updated in Drupal 6, even if they +are not enabled. That means that modules that rely on core CCK may try +to run their updates even if core CCK is not enabled, and contributed +CCK modules that have broken updates will have their broken updates +run even if they are not enabled. + +A number of updates are dependent on other updates and won't work +until previous updates are finished or specific modules are enabled, +so you may get messages that other modules need to be enabled or that +update.php needs to be re-run, and you need to follow those instructions +until all the updates complete. + +Taking extra time during the upgrade by leaving modules out of the +modules folder altogether until you are ready to enable and update them +should reduce or eliminate update problems. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/content.info b/drupal/sites/default/boinc/modules/contrib/cck/content.info new file mode 100644 index 0000000000000000000000000000000000000000..6f398eb6445f078262b8b723a9ed0f9218054765 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/content.info @@ -0,0 +1,11 @@ +; $Id$ +name = Content +description = Allows administrators to define new content types. +package = CCK +core = 6.x +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/content.install b/drupal/sites/default/boinc/modules/contrib/cck/content.install new file mode 100644 index 0000000000000000000000000000000000000000..9faaac4558006fefb57a18c9c80dc2db241aaa5a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/content.install @@ -0,0 +1,621 @@ +<?php +// $Id$ + +function content_requirements($phase) { + $requirements = array(); + // Ensure translations don't break at install time + $t = get_t(); + if (module_exists('views') && (!function_exists('views_api_version') || views_api_version() < 2.0)) { + $requirements['cck_views'] = array( + 'title' => $t('CCK - No Views integration'), + 'description' => $t("CCK integration with Views module requires Views 6.x-2.0-rc2 or greater."), + 'severity' => REQUIREMENT_ERROR, + ); + } + return $requirements; +} + +/** + * 'Safe' version of content_types() to use in updates and installs. + * + * Can't safely use content_fields() or content_types() in an update to get + * a fields array, especially without knowing what field modules are enabled, + * or the current state of the database and cache, so create a fields array + * from database info that is limited to fields from modules that are + * currently enabled. + */ +function content_types_install() { + drupal_load('module', 'content'); + module_load_include('inc', 'content', '/includes/content.crud'); + $module_field_types = $module_widgets = array(); + foreach (module_list() as $module) { + if ($field_type = module_invoke($module, 'field_info')) { + $module_field_types[$module] = $field_type; + } + if ($widget_type = module_invoke($module, 'widget_info')) { + $module_widgets[$module] = $widget_type; + } + } + $fields = array(); + $db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ". + " LEFT JOIN {". content_field_tablename() ."} nf ON nf.field_name = nfi.field_name"); + while ($row = db_fetch_array($db_result)) { + $field = array_merge($row, unserialize($row['global_settings'])); + unset($field['global_settings']); + + // There may be module data available for currently disabled modules, + // or missing module data for currently enabled modules, so start over + // to get only field info for enabled modules. + unset($field['module']); + unset($field['widget_module']); + // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'. + $field['columns'] = isset($field['db_columns']) ? $field['db_columns'] : array(); + unset($field['db_columns']); + + foreach ($module_field_types as $module => $types) { + foreach ($types as $type_name => $type) { + if ($field['type'] == $type_name) { + $field['module'] = $module; + } + } + } + foreach ($module_widgets as $module => $types) { + foreach ($types as $type_name => $type) { + if ($field['widget_type'] == $type_name) { + $field['widget_module'] = $module; + } + } + } + if (!empty($field['module']) && !empty($field['widget_module'])) { + $field['widget_settings'] = unserialize($field['widget_settings']); + $field['display_settings'] = unserialize($field['display_settings']); + $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field); + $field = content_field_instance_expand($field); + $fields[$field['type_name']][$field['field_name']] = $field; + } + } + return $fields; +} + +/** + * Implementation of hook_install(). + */ +function content_install() { + variable_set('content_schema_version', 6009); + drupal_install_schema('content'); +} + + +/** + * Implementation of hook_uninstall(). + */ +function content_uninstall() { + drupal_uninstall_schema('content'); + // The variable is used during the uninstall process, + // so we removed it at the very end. + variable_del('content_schema_version'); + // Remove extra weights. + foreach (node_get_types('names') as $type_name) { + variable_del("content_extra_weights_$type_name"); + } +} + +/** + * Implementation of hook_enable(). + */ +function content_enable() { + // Make sure old data is emptied out of the caches, since it + // may no longer be valid since the module was last enabled, + // especially if not all the same field modules are enabled + // as before. Especially needed during updates. + cache_clear_all('*', 'cache_content', TRUE); + content_clear_type_cache(TRUE); +} + +/** + * Implementation of hook_disable(). + */ +function content_disable() { + // Make sure old data is emptied out of the caches, since it + // may no longer be valid when the module is re-enabled. + cache_clear_all('*', 'cache_content', TRUE); + content_clear_type_cache(TRUE); +} + +/** + * Implementation of hook_schema. + */ +function content_schema() { + + // Static (meta) tables. + + $schema['content_node_field'] = array( + 'fields' => array( + 'field_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'type' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''), + 'global_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE), + 'required' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), + 'multiple' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), + 'db_storage' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 1), + 'module' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''), + 'db_columns' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE), + 'active' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), + 'locked' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), + ), + 'primary key' => array('field_name'), + ); + $schema['content_node_field_instance'] = array( + 'fields' => array( + 'field_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'type_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), + 'label' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'widget_type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'widget_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE), + 'display_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE), + 'description' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE), + 'widget_module' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''), + 'widget_active' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0), + ), + 'primary key' => array('field_name', 'type_name'), + ); + $schema['cache_content'] = drupal_get_schema_unprocessed('system', 'cache'); + + // When the module is first installed, the remaining code in the schema + // will create errors, since these tables have not yet been created. + // We don't need to create data tables on initial installation anyway + // since no fields have been created yet, so just return with this much + // of the schema. + + if (!db_table_exists('content_node_field') || !db_table_exists('content_node_field_instance')) { + return $schema; + } + + // Dynamic (data) tables. + + drupal_load('module', 'content'); + + // We can't use many helper functions here, like content_fields() or + // content_types() or we risk creating a fatal loop from circular + // logic when they call other functions that use this schema, so create + // the schema directly from a fresh query of the database. + + // content_table_schema() and content_database_info() have no + // circular logic and are safe to use here. + + $db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ". + " LEFT JOIN {". content_field_tablename() ."} nf ON nf.field_name = nfi.field_name WHERE nf.active = 1 AND nfi.widget_active = 1"); + while ($field = db_fetch_array($db_result)) { + // 'columns' is a reserved word in MySQL4, so our db column is named 'db_columns'. + $field['columns'] = unserialize($field['db_columns']); + unset($field['db_columns']); + + $content_table = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + $field_table = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD); + + + // We always add a 'per content type' table for each content type that + // has fields. + if (!isset($schema[$content_table])) { + $schema[$content_table] = content_table_schema(); + } + + $base_schema = content_table_schema($field); + if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) { + // Per-field storage: add the 'per field' table if needed. + if (!isset($schema[$field_table])) { + $schema[$field_table] = $base_schema; + } + } + else { + // Per-type storage: merge the information for the field + // in the existing table. + $schema[$content_table]['fields'] = array_merge($schema[$content_table]['fields'], $base_schema['fields']); + $schema[$content_table]['content fields'] = array_merge($schema[$content_table]['content fields'], $base_schema['content fields']); + } + } + return $schema; +} + +function content_update_last_removed() { + return 1008; +} + +/** + * Helper function for module updates : + * - checks no updates are pending for content.module + * - checks content module and the module being updated are both enabled. + * + * @param $module + * The name of the module being updated. + */ +function content_check_update($module = NULL) { + $ret = array(); + // Check that modules are enabled before running their updates. + if (!module_exists('content') || ($module && !module_exists($module))) { + drupal_set_message(t("Updates for CCK-related modules are not run until the modules are enabled on the <a href=\"@admin-modules-path\">administer modules page</a>. When you enable them, you'll need to return to <a href=\"@update-php\">update.php</a> and run the remaining updates.", array('@admin-modules-path' => url('admin/build/modules'), '@update-php' => base_path() .'update.php?op=selection')), 'warning', FALSE); + // The content module is not enabled, nothing else can happen. + if ($module && !module_exists('content') && module_exists($module)) { + $query_message = t('!module.module has updates but cannot be updated because content.module is not enabled.<br />If and when content.module is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run.', array('!module' => $module)); + } + // The requested module is not enabled, which may be intentional. + // Just let the user know there are updates to be processed if enabled later. + else { + $query_message = t('!module.module has updates and is available in the modules folder but is not enabled.<br />If and when it is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run.', array('!module' => $module ? $module : 'content')); + } + $ret['#abort'] = array('success' => FALSE, 'query' => $query_message); + return $ret; + } + // Check that content.module is up-to-date before running field module updates. + if ($module && (drupal_get_installed_schema_version('content', TRUE) < max(drupal_get_schema_versions('content')))) { + drupal_set_message(t('Some updates are still pending. Please return to <a href="@update-php">update.php</a> and run the remaining updates.', array('@update-php' => base_path() .'update.php?op=selection')), 'warning', FALSE); + $ret['#abort'] = array('success' => FALSE, 'query' => t('Some updates are still pending.<br/>Please re-run the update script.')); + return $ret; + } + // If everything is OK and updates are not aborted, make sure + // content_associate_fields() gets run. With all the complexity of + // the dependent updates, it can get missed when an update is aborted. + // It won't hurt anything to do this more than once in order to be sure + // it doesn't get skipped. Without this step, we can end up with + // field modules that are enabled and updated, but not marked as active + // in the content_node_field table. + if ($module and module_exists($module)) { + content_associate_fields($module); + } +} + +/** + * Add module name to fields table to make it easier to identify the fields to delete when a module + * is uninstalled. + * + * Needed because the value drops out of content_info() when module is disabled, so there + * is no other way to find the associated fields. + */ +function content_update_6000() { + if ($abort = content_check_update()) { + return $abort; + } + + $ret = array(); + + drupal_load('module', 'content'); + if (db_column_exists(content_field_tablename(), 'active')) { + return $ret; + } + db_add_field($ret, content_field_tablename(), 'module', array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => '')); + db_add_field($ret, content_field_tablename(), 'db_columns', array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'initial' => '')); + db_add_field($ret, content_field_tablename(), 'active', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0)); + db_add_field($ret, content_instance_tablename(), 'widget_module', array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => '')); + db_add_field($ret, content_instance_tablename(), 'widget_active', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0)); + + // This will update the table for any modules enabled at this time. + foreach (module_list() as $module) { + content_associate_fields($module); + } + + // Fix the cache_content schema + if (db_table_exists('cache_content')) { + db_drop_table($ret, 'cache_content'); + } + db_create_table($ret, 'cache_content', drupal_get_schema_unprocessed('system', 'cache')); + variable_set('content_schema_version', 6000); + + // The cache table had to be used to store data until this update ran, + // so clear cache out now that we're switching back to the cache_content table. + $ret[] = update_sql('DELETE FROM {cache}'); + + return $ret; +} + +/** + * Rename node_field and node_field_instance tables. + * + * This is a carryover from when the data tables were renamed, + * postponed so we wouldn't create any more havoc than necessary + * until a major version change. + * + * Using 'content_node_field' instead of 'content_field' + * to avoid conflicts with field tables that will be prefixed + * with 'content_field'. + */ +function content_update_6001() { + if ($abort = content_check_update()) { + return $abort; + } + + $ret = array(); + drupal_load('module', 'content'); + if (db_table_exists('content_node_field')) { + return $ret; + } + db_rename_table($ret, 'node_field', 'content_node_field'); + db_rename_table($ret, 'node_field_instance', 'content_node_field_instance'); + variable_set('content_schema_version', 6001); + content_clear_type_cache(TRUE); + return $ret; +} + +/** + * Get rid of automatic per content tables for content types that have no fields. + * Switching to adding those tables only when needed. + */ +function content_update_6002() { + if ($abort = content_check_update()) { + return $abort; + } + + $ret = array(); + + drupal_load('module', 'content'); + $db_types = content_types_install(); + $field_types = array(); + + $result = db_query("SELECT DISTINCT type_name FROM {". content_instance_tablename() ."}"); + while ($type = db_fetch_array($result)) { + $field_types[] = $type['type_name']; + } + + foreach ($db_types as $content_type => $content_info) { + if (!in_array($content_type, $field_types)) { + $table = _content_tablename($content_type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + if (db_table_exists($table)) { + db_drop_table($ret, $table); + } + } + } + variable_set('content_schema_version', 6002); + content_clear_type_cache(TRUE); + return $ret; +} + +/** + * 'db_columns' column 1st got introduced as 'columns', which is forbidden in MySQL 4. + * This update function will only be useful for early D6 testers... + */ +function content_update_6003() { + if ($abort = content_check_update()) { + return $abort; + } + + $ret = array(); + if (db_column_exists('content_node_field', 'columns')) { + db_change_field($ret, 'content_node_field', 'columns', 'db_columns', array('type' => 'text', 'size' => 'medium', 'not null' => TRUE)); + } + variable_set('content_schema_version', 6003); + return $ret; +} + +/** + * Index the 'nid' column on data tables to optimize node deletion. + * Large tables might deserve a multipass update. + */ +function content_update_6004(&$sandbox) { + if ($abort = content_check_update()) { + return $abort; + } + + $ret = array(); + + // Do nothing if the indexes were already created by D5's content_update_1009. + if (variable_get('content_update_1009', FALSE)) { + return $ret; + } + + // Gather list of tables. + if (!isset($sandbox['tables'])) { + drupal_load('module', 'content'); + $sandbox['tables'] = array(); + $result = db_query('SELECT * FROM {'. content_instance_tablename() .'} nfi '. + ' LEFT JOIN {'. content_field_tablename() .'} nf ON nf.field_name = nfi.field_name'); + while ($field = db_fetch_array($result)) { + if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) { + $table = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD); + } + else { + $table = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + } + $sandbox['tables'][$table] = $table; + } + $sandbox['count'] = count($sandbox['tables']); + } + + // One pass : add index on one table. + if ($table = array_shift($sandbox['tables'])) { + db_add_index($ret, $table, 'nid', array('nid')); + } + + if ($sandbox['count']) { + $ret['#finished'] = 1 - count($sandbox['tables']) / $sandbox['count']; + } + variable_set('content_schema_version', 6004); + return $ret; +} + +/** + * Add 'locked' property for fields. + */ +function content_update_6005() { + if ($abort = content_check_update()) { + return $abort; + } + + $ret = array(); + drupal_load('module', 'content'); + db_add_field($ret, content_field_tablename(), 'locked', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0)); + variable_set('content_schema_version', 6005); + return $ret; +} + +/** + * Make sure the 'locked' column is NOT NULL (error in previous content_update_6005(). + */ +function content_update_6006() { + if ($abort = content_check_update()) { + return $abort; + } + + $ret = array(); + drupal_load('module', 'content'); + db_change_field($ret, content_field_tablename(), 'locked', 'locked', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0)); + variable_set('content_schema_version', 6006); + return $ret; +} + +/** + * Dummy update function to make sure the theme registry and css / JS aggregated files + * are updated. + */ +function content_update_6007() { + if ($abort = content_check_update()) { + return $abort; + } + + variable_set('content_schema_version', 6007); + return array(); +} + +/** + * Dummy update function to make sure schema version gets updated. + */ +function content_update_6008() { + if ($abort = content_check_update()) { + return $abort; + } + + variable_set('content_schema_version', 6008); + return array(); +} + +/** + * Add the 'exclude from $content' display setting to all existing field instances. + */ +function content_update_6009() { + if ($abort = content_check_update()) { + return $abort; + } + + $ret = array(); + $result = db_query("SELECT * FROM {content_node_field_instance}"); + while ($type = db_fetch_array($result)) { + $new_settings = array(); + $display_settings = unserialize($type['display_settings']); + if (!empty($display_settings)) { + foreach ($display_settings as $key => $val) { + $new_settings[$key] = $val; + if ($key !== 'label' && is_array($val)) { + $new_settings[$key]['exclude'] = 0; + } + } + } + else { + $new_settings = array( + 'label' => array('format' => 'above'), + 'full' => array('format' => 'default', 'exclude' => 0), + 'teaser' => array('format' => 'default', 'exclude' => 0), + ); + } + db_query("UPDATE {content_node_field_instance} SET display_settings='%s' WHERE field_name='%s' AND type_name='%s'", serialize($new_settings), $type['field_name'], $type['type_name']); + } + variable_set('content_schema_version', 6009); + return $ret; +} + +/** + * Fix multiple serialization caused by per-field to per-type migration. + * See http://drupal.org/node/407446. + */ +function content_update_6010(&$sandbox) { + if ($abort = content_check_update()) { + return $abort; + } + $ret = array(); + + drupal_load('module', 'content'); + + // Gather list of tables and columns that need to be updated. + if (!isset($sandbox['tables'])) { + $sandbox['tables'] = array(); + $fields = content_fields(); + foreach ($fields as $name => $field) { + $db_info = content_database_info($field); + foreach ($db_info['columns'] as $column => $attributes) { + if (isset($attributes['serialize']) && $attributes['serialize']) { + $sandbox['tables'][$db_info['table']]['table'] = $db_info['table']; + $sandbox['tables'][$db_info['table']]['columns'][] = $attributes['column']; + $sandbox['tables'][$db_info['table']]['multiple'] = $field['multiple']; + } + } + } + $sandbox['count'] = count($sandbox['tables']); + $sandbox['current_vid'] = 0; + $sandbox['current_delta'] = 0; + } + + // Number of rows to fix in one pass. + $limit = 500; + // Start correcting data. + if ($table_info = array_shift($sandbox['tables'])) { + $table = $table_info['table']; + $columns = $table_info['columns']; + + if ($table_info['multiple']) { + $query = "SELECT * FROM {" . $table . "} WHERE (vid = %d AND delta > %d) OR (vid > %d) ORDER BY vid ASC, delta ASC"; + $args = array($sandbox['current_vid'], $sandbox['current_delta'], $sandbox['current_vid']); + } + else { + $query = "SELECT * FROM {" . $table . "} WHERE vid > %d ORDER BY vid ASC"; + $args = array($sandbox['current_vid']); + } + $result = db_query_range($query, $args, 0, $limit); + $count = 0; + while ($row = db_fetch_array($result)) { + $update_query = $update_args = array(); + foreach ($columns as $column) { + $data = $row[$column]; + // No need to do anything if the data is NULL. + if (!empty($data)) { + // Unserialize until we get something that is not a string + while (is_string($data)) { + $unserialized = @unserialize($data); + if ($unserialized !== FALSE) { + $data = $unserialized; + } + else { + // TODO : test with a serialized string, just in case... + break; + } + } + // Re-serialize once. + $data = serialize($data); + // If we end up with something different than what we started with, update. + if ($data !== $row[$column]) { + $update_query[] = "$column = '%s'"; + $update_args[] = $data; + } + } + } + if ($update_query) { + $update_args[] = $row['vid']; + db_query("UPDATE {" . $table . "} SET ". implode(', ', $update_query) ." WHERE vid = %d", $update_args); + } + $sandbox['current_vid'] = $row['vid']; + $sandbox['current_delta'] = isset($row['delta']) ? $row['delta'] : 0; + $count++; + } + if ($count == $limit) { + // Add the table back into the list of tables to be processed if rows remain. + array_unshift($sandbox['tables'], $table_info); + } + else { + // Done with this table: reset vid and delta markers. + $sandbox['current_vid'] = 0; + $sandbox['current_delta'] = 0; + $ret[] = array('success' => TRUE, 'query' => "Fixed serialized values in table $table"); + } + } + + if ($sandbox['count']) { + $ret['#finished'] = 1 - count($sandbox['tables']) / $sandbox['count']; + } + return $ret; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/content.js b/drupal/sites/default/boinc/modules/contrib/cck/content.js new file mode 100644 index 0000000000000000000000000000000000000000..72a2f2a7a7ed034e49b8a49774f8c6d33fa153f8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/content.js @@ -0,0 +1,80 @@ +// $Id$ + +Drupal.behaviors.cckManageFields = function(context) { + attachUpdateSelects(context); +}; + +function attachUpdateSelects(context) { + var widgetTypes = Drupal.settings.contentWidgetTypes; + var fields = Drupal.settings.contentFields; + + // Store the default text of widget selects. + $('#content-field-overview .content-widget-type-select', context).each(function() { + this.initialValue = this.options[0].text; + }); + + // 'Field type' select updates its 'Widget' select. + $('#content-field-overview .content-field-type-select', context).each(function() { + this.targetSelect = $('.content-widget-type-select', $(this).parents('tr').eq(0)); + + $(this).change(function() { + var selectedFieldType = this.options[this.selectedIndex].value; + var options = (selectedFieldType in widgetTypes) ? widgetTypes[selectedFieldType] : [ ]; + this.targetSelect.contentPopulateOptions(options); + }); + + // Trigger change on initial pageload to get the right widget options + // when field type comes pre-selected (on failed validation). + $(this).trigger('change'); + }); + + // 'Existing field' select updates its 'Widget' select and 'Label' textfield. + $('#content-field-overview .content-field-select', context).each(function() { + this.targetSelect = $('.content-widget-type-select', $(this).parents('tr').eq(0)); + this.targetTextfield = $('.content-label-textfield', $(this).parents('tr').eq(0)); + + $(this).change(function(e, updateText) { + var updateText = (typeof(updateText) == 'undefined') ? true : updateText; + var selectedField = this.options[this.selectedIndex].value; + var selectedFieldType = (selectedField in fields) ? fields[selectedField].type : null; + var selectedFieldWidget = (selectedField in fields) ? fields[selectedField].widget : null + var options = (selectedFieldType && (selectedFieldType in widgetTypes)) ? widgetTypes[selectedFieldType] : [ ]; + this.targetSelect.contentPopulateOptions(options, selectedFieldWidget); + + if (updateText) { + $(this.targetTextfield).attr('value', (selectedField in fields) ? fields[selectedField].label : ''); + } + }); + + // Trigger change on initial pageload to get the right widget options + // and label when field type comes pre-selected (on failed validation). + $(this).trigger('change', false); + }); +} + +jQuery.fn.contentPopulateOptions = function(options, selected) { + return this.each(function() { + var disabled = false; + if (options.length == 0) { + options = [this.initialValue]; + disabled = true; + } + + // If possible, keep the same widget selected when changing field type. + // This is based on textual value, since the internal value might be + // different (optionwidgets_buttons vs. nodereference_buttons). + var previousSelectedText = this.options[this.selectedIndex].text; + + var html = ''; + jQuery.each(options, function(value, text) { + // Figure out which value should be selected. The 'selected' param + // takes precedence. + var is_selected = ((typeof(selected) !== 'undefined' && value == selected) || (typeof(selected) == 'undefined' && text == previousSelectedText)); + html += '<option value="' + value + '"' + (is_selected ? ' selected="selected"' : '') +'>' + text + '</option>'; + }); + + $(this) + .html(html) + .attr('disabled', disabled ? 'disabled' : ''); + }); +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/content.module b/drupal/sites/default/boinc/modules/contrib/cck/content.module new file mode 100644 index 0000000000000000000000000000000000000000..b679339ecf8807d97a90d84e1f50a464d2a3b15f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/content.module @@ -0,0 +1,2709 @@ +<?php +// $Id$ +/** + * @file + * Allows administrators to associate custom fields to content types. + */ + +define('CONTENT_DB_STORAGE_PER_FIELD', 0); +define('CONTENT_DB_STORAGE_PER_CONTENT_TYPE', 1); + +define('CONTENT_CALLBACK_NONE', 0x0001); +define('CONTENT_CALLBACK_DEFAULT', 0x0002); +define('CONTENT_CALLBACK_CUSTOM', 0x0004); + +define('CONTENT_HANDLE_CORE', 0x0001); +define('CONTENT_HANDLE_MODULE', 0x0002); + +function content_help($path, $arg) { + switch ($path) { + case 'admin/help#content': + $output = '<p>'. t('The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default "Title" and "Body" may be added. CCK features are accessible through tabs on the <a href="@content-types">content types administration page</a>. (See the <a href="@node-help">node module help page</a> for more information about content types.)', array('@content-types' => url('admin/content/types'), '@node-help' => url('admin/help/node'))) .'</p>'; + $output .= '<p>'. t('When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a "person" may have multiple e-mail addresses) or a single value (i.e., an "employee" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules.') .'</p>'; + $output .= '<p>'. t('Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href="@modules">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:', array('@modules' => url('admin/build/modules'))) .'</p>'; + $output .= '<ul>'; + $output .= '<li>'. t('<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available.') .'</li>'; + $output .= '<li>'. t("<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values.") .'</li>'; + $output .= '<li>'. t('<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple "employee" nodes may contain a <em>nodereference</em> field linking to an "employer" node).') .'</li>'; + $output .= '<li>'. t('<em>userreference</em>, which creates custom references to your sites\' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site\'s users and posts. To track user involvement in a post beyond Drupal\'s standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named "Edited by" to a content type to store a link to an editor\'s user account page.') .'</li>'; + $output .= '<li>'. t('<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module.') .'</li>'; + $output .= '</ul>'; + $output .= '<p>'. t('For more information, see the online handbook entry for <a href="@handbook-cck">CCK</a> or the <a href="@project-cck">CCK project page</a>.', array('@handbook-cck' => 'http://drupal.org/handbook/modules/cck', '@project-cck' => 'http://drupal.org/project/cck')) .'</p>'; + return $output; + } +} + +/** + * Implementation of hook_flush_caches. + */ +function content_flush_caches() { + return array(content_cache_tablename()); +} + +/** + * Implementation of hook_init(). + */ +function content_init() { + drupal_add_css(drupal_get_path('module', 'content') .'/theme/content-module.css'); + if (module_exists('token') && !function_exists('content_token_values')) { + module_load_include('inc', 'content', 'includes/content.token'); + } + if (module_exists('diff') && !function_exists('content_diff')) { + module_load_include('inc', 'content', 'includes/content.diff'); + } +} + +/** + * Implementation of hook_perm(). + */ +function content_perm() { + return array('Use PHP input for field settings (dangerous - grant with care)'); +} + +/** + * Implementation of hook_menu_alter(). + */ +function content_menu_alter(&$items) { + // Customize the content types page with our own callback + $items['admin/content/types']['page callback'] = 'content_types_overview'; + $items['admin/content/types']['file'] = 'content.admin.inc'; + $items['admin/content/types']['file path'] = drupal_get_path('module', 'content') .'/includes'; +} + +/** + * Implementation of hook_menu(). + */ +function content_menu() { + $items = array(); + $items['admin/content/types/fields'] = array( + 'title' => 'Fields', + 'page callback' => 'content_fields_list', + 'access arguments' => array('administer content types'), + 'file' => 'includes/content.admin.inc', + 'type' => MENU_LOCAL_TASK, + ); + // Callback for AHAH add more buttons. + $items['content/js_add_more'] = array( + 'page callback' => 'content_add_more_js', + 'access arguments' => array('access content'), + 'file' => 'includes/content.node_form.inc', + 'type' => MENU_CALLBACK, + ); + + // Make sure this doesn't fire until content_types is working, + // and tables are updated, needed to avoid errors on initial installation. + if (!defined('MAINTENANCE_MODE') && variable_get('content_schema_version', -1) >= 6007) { + foreach (node_get_types() as $type) { + $type_name = $type->type; + $content_type = content_types($type_name); + $type_url_str = $content_type['url_str']; + $items['admin/content/node-type/'. $type_url_str .'/fields'] = array( + 'title' => 'Manage fields', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('content_field_overview_form', $type_name), + 'access arguments' => array('administer content types'), + 'file' => 'includes/content.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => 1, + ); + $items['admin/content/node-type/'. $type_url_str .'/display'] = array( + 'title' => 'Display fields', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('content_display_overview_form', $type_name), + 'access arguments' => array('administer content types'), + 'file' => 'includes/content.admin.inc', + 'type' => MENU_LOCAL_TASK, + 'weight' => 2, + ); + $contexts = content_build_modes('_tabs'); + foreach ($contexts as $key => $tab) { + $items['admin/content/node-type/'. $type_url_str .'/display/'. $key] = array( + 'title' => $tab['title'], + 'page arguments' => array('content_display_overview_form', $type_name, $key), + 'access arguments' => array('administer content types'), + 'type' => $key == 'basic' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + 'weight' => $key == 'basic' ? 0 : 1, + ); + } + // Cast as an array in case this is called before any fields have + // been added, like when a new content type is created. + foreach ((array) $content_type['fields'] as $field) { + $field_name = $field['field_name']; + $items['admin/content/node-type/'. $type_url_str .'/fields/'. $field_name] = array( + 'title' => $field['widget']['label'], + 'page callback' => 'drupal_get_form', + 'page arguments' => array('content_field_edit_form', $type_name, $field_name), + 'access arguments' => array('administer content types'), + 'file' => 'includes/content.admin.inc', + 'type' => MENU_LOCAL_TASK, + ); + $items['admin/content/node-type/'. $type_url_str .'/fields/'. $field_name .'/remove'] = array( + 'title' => 'Remove field', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('content_field_remove_form', $type_name, $field_name), + 'access arguments' => array('administer content types'), + 'file' => 'includes/content.admin.inc', + 'type' => MENU_CALLBACK, + ); + } + } + } + return $items; +} + +/** + * Hook elements(). + * + * Used to add multiple value processing, validation, and themes. + * + * FAPI callbacks can be declared here, and the element will be + * passed to those callbacks. + * + * Drupal will automatically theme the element using a theme with + * the same name as the hook_elements key. + */ +function content_elements() { + return array( + 'content_multiple_values' => array(), + 'content_field' => array(), + ); +} + +/** + * Implementation of hook_theme(). + */ +function content_theme() { + $path = drupal_get_path('module', 'content') .'/theme'; + require_once "./$path/theme.inc"; + + return array( + 'content_field' => array( + 'template' => 'content-field', + 'arguments' => array('element' => NULL), + 'path' => $path, + ), + 'content_overview_links' => array( + 'arguments' => array(), + ), + 'content_field_overview_form' => array( + 'template' => 'content-admin-field-overview-form', + 'file' => 'theme.inc', + 'path' => $path, + 'arguments' => array('form' => NULL), + ), + 'content_display_overview_form' => array( + 'template' => 'content-admin-display-overview-form', + 'file' => 'theme.inc', + 'path' => $path, + 'arguments' => array('form' => NULL), + ), + 'content_exclude' => array( + 'arguments' => array('content' => NULL, 'object' => array(), 'context' => NULL), + ), + 'content_view_multiple_field' => array( + 'arguments' => array('items' => NULL, 'field' => NULL, 'data' => NULL), + ), + 'content_multiple_values' => array( + 'arguments' => array('element' => NULL), + ), + ); +} + +/** + * Implementation of hook_views_api(). + */ +function content_views_api() { + return array( + 'api' => 2, + 'path' => drupal_get_path('module', 'content') . '/includes/views', + ); +} + +/** + * Implementation of hook_ctools_plugin_directory(). + */ +function content_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && $plugin == 'content_types') { + return 'includes/panels/' . $plugin; + } +} + +/** + * Load data for a node type's fields. + * Implementation of hook_nodeapi 'load' op. + * + * When loading one of the content.module nodes, we need to let each field handle + * its own loading. This can make for a number of queries in some cases, so we + * cache the loaded object structure and invalidate it during the update process. + */ +function content_load(&$node) { + $cid = 'content:'. $node->nid .':'. $node->vid; + if ($cached = cache_get($cid, content_cache_tablename())) { + foreach ($cached->data as $key => $value) { + $node->$key = $value; + } + } + else { + $default_additions = _content_field_invoke_default('load', $node); + if ($default_additions) { + foreach ($default_additions as $key => $value) { + $node->$key = $value; + } + } + $additions = _content_field_invoke('load', $node); + if ($additions) { + foreach ($additions as $key => $value) { + $node->$key = $value; + $default_additions[$key] = $value; + } + } + cache_set($cid, $default_additions, content_cache_tablename()); + } +} + +/** + * Implementation of hook_nodeapi 'validate' op. + * + */ +function content_validate(&$node, $form = NULL) { + _content_field_invoke('validate', $node, $form); + _content_field_invoke_default('validate', $node, $form); +} + +/** + * Implementation of hook_nodeapi 'presave' op. + * + */ +function content_presave(&$node) { + _content_field_invoke('presave', $node); + _content_field_invoke_default('presave', $node); +} + +/** + * Implementation of hook_nodeapi 'insert' op. + * + * Insert node type fields. + */ +function content_insert(&$node) { + _content_field_invoke('insert', $node); + _content_field_invoke_default('insert', $node); +} + +/** + * Implementation of hook_nodeapi 'update' op. + * + * Update node type fields. + */ +function content_update(&$node) { + _content_field_invoke('update', $node); + _content_field_invoke_default('update', $node); + cache_clear_all('content:'. $node->nid .':'. $node->vid, content_cache_tablename()); +} + +/** + * Implementation of hook_nodeapi 'delete' op. + * + * Delete node type fields. + */ +function content_delete(&$node) { + _content_field_invoke('delete', $node); + _content_field_invoke_default('delete', $node); + cache_clear_all('content:'. $node->nid .':', content_cache_tablename(), TRUE); +} + +/** + * Implementation of hook_nodeapi 'delete_revision' op. + * + * Delete node type fields for a revision. + */ +function content_delete_revision(&$node) { + _content_field_invoke('delete revision', $node); + _content_field_invoke_default('delete revision', $node); + cache_clear_all('content:'. $node->nid .':'. $node->vid, content_cache_tablename()); +} + +/** + * Implementation of hook_nodeapi 'view' op. + * + * Generate field render arrays. + */ +function content_view(&$node, $teaser = FALSE, $page = FALSE) { + // Let field modules sanitize their data for output. + _content_field_invoke('sanitize', $node, $teaser, $page); + + // Merge fields. + $additions = _content_field_invoke_default('view', $node, $teaser, $page); + $node->content = array_merge((array) $node->content, $additions); +} + +/** + * Render a single field, fully themed with label and multiple values. + * + * To be used by third-party code (Views, Panels...) that needs to output + * an isolated field. Do *not* use inside node templates, use the + * $FIELD_NAME_rendered variables instead. + * + * By default, the field is displayed using the settings defined for the + * 'full node' or 'teaser' contexts (depending on the value of the $teaser param). + * Set $node->build_mode to a different value to use a different context. + * + * Different settings can be specified by adjusting $field['display_settings']. + * + * @param $field + * The field definition. + * @param $node + * The node containing the field to display. Can be a 'pseudo-node', containing + * at least 'type', 'nid', 'vid', and the field data. + * @param $teaser + * @param $page + * Similar to hook_nodeapi('view') + * @return + * The themed output for the field. + */ +function content_view_field($field, $node, $teaser = FALSE, $page = FALSE) { + $output = ''; + if (isset($node->$field['field_name'])) { + $items = $node->$field['field_name']; + + // Use 'full'/'teaser' if not specified otherwise. + $node->build_mode = isset($node->build_mode) ? $node->build_mode : NODE_BUILD_NORMAL; + + // One-field equivalent to _content_field_invoke('sanitize'). + $field_types = _content_field_types(); + $module = $field_types[$field['type']]['module']; + $function = $module .'_field'; + if (function_exists($function)) { + $function('sanitize', $node, $field, $items, $teaser, $page); + $node->$field['field_name'] = $items; + } + + $view = content_field('view', $node, $field, $items, $teaser, $page); + // content_field('view') adds a wrapper to handle variables and 'excluded' + // fields for node templates. We bypass it and render the actual field. + $output = drupal_render($view[$field['field_name']]['field']); + } + return $output; +} + +/** + * Implementation of hook_nodeapi 'alter' op. + * + * Add back the formatted values in the 'view' element for all fields, + * so that node templates can use it. + */ +function content_alter(&$node, $teaser = FALSE, $page = FALSE) { + _content_field_invoke_default('alter', $node, $teaser, $page); +} + +/** + * Implementation of hook_nodeapi 'prepare translation' op. + * + * Generate field render arrays. + */ +function content_prepare_translation(&$node) { + $default_additions = _content_field_invoke_default('prepare translation', $node); + $additions = _content_field_invoke('prepare translation', $node); + // Merge module additions after the default ones to enable overriding + // of field values. + $node = (object) array_merge((array) $node, $default_additions, $additions); +} + +/** + * Implementation of hook_nodeapi(). + */ +function content_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { + // Prevent against invalid 'nodes' built by broken 3rd party code. + if (isset($node->type)) { + $type = content_types($node->type); + // Save cycles if the type has no CCK fields. + if (!empty($type['fields'])) { + $callback = 'content_'. str_replace(' ', '_', $op); + if (function_exists($callback)) { + $callback($node, $a3, $a4); + } + } + + // Special case for 'view' op, we want to adjust weights of non-cck fields + // even if there are no actual fields for this type. + if ($op == 'view') { + $node->content['#pre_render'][] = 'content_alter_extra_weights'; + $node->content['#content_extra_fields'] = $type['extra']; + } + } +} + +/** + * Implementation of hook_form_alter(). + */ +function content_form_alter(&$form, $form_state, $form_id) { + if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) { + $type = content_types($form['#node']->type); + if (!empty($type['fields'])) { + module_load_include('inc', 'content', 'includes/content.node_form'); + // Merge field widgets. + $form = array_merge($form, content_form($form, $form_state)); + } + $form['#pre_render'][] = 'content_alter_extra_weights'; + $form['#content_extra_fields'] = $type['extra']; + } +} + +/** + * Pre-render callback to adjust weights of non-CCK fields. + */ +function content_alter_extra_weights($elements) { + if (isset($elements['#content_extra_fields'])) { + foreach ($elements['#content_extra_fields'] as $key => $value) { + // Some core 'fields' use a different key in node forms and in 'view' + // render arrays. Check we're not on a form first. + if (!isset($elements['#build_id']) && isset($value['view']) && isset($elements[$value['view']])) { + $elements[$value['view']]['#weight'] = $value['weight']; + } + elseif (isset($elements[$key])) { + $elements[$key]['#weight'] = $value['weight']; + } + } + } + return $elements; +} + +/** + * Proxy function to call content_add_more_submit(), because it might not be + * included yet when the form is processed and invokes the callback. + */ +function content_add_more_submit_proxy($form, &$form_state) { + module_load_include('inc', 'content', 'includes/content.node_form'); + content_add_more_submit($form, $form_state); +} + +/** + * Theme an individual form element. + * + * Combine multiple values into a table with drag-n-drop reordering. + */ +function theme_content_multiple_values($element) { + $field_name = $element['#field_name']; + $field = content_fields($field_name); + $output = ''; + + if ($field['multiple'] >= 1) { + $table_id = $element['#field_name'] .'_values'; + $order_class = $element['#field_name'] .'-delta-order'; + $required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : ''; + + $header = array( + array( + 'data' => t('!title: !required', array('!title' => $element['#title'], '!required' => $required)), + 'colspan' => 2 + ), + t('Order'), + ); + $rows = array(); + + // Sort items according to '_weight' (needed when the form comes back after + // preview or failed validation) + $items = array(); + foreach (element_children($element) as $key) { + if ($key !== $element['#field_name'] .'_add_more') { + $items[] = &$element[$key]; + } + } + usort($items, '_content_sort_items_value_helper'); + + // Add the items as table rows. + foreach ($items as $key => $item) { + $item['_weight']['#attributes']['class'] = $order_class; + $delta_element = drupal_render($item['_weight']); + $cells = array( + array('data' => '', 'class' => 'content-multiple-drag'), + drupal_render($item), + array('data' => $delta_element, 'class' => 'delta-order'), + ); + $rows[] = array( + 'data' => $cells, + 'class' => 'draggable', + ); + } + + $output .= theme('table', $header, $rows, array('id' => $table_id, 'class' => 'content-multiple-table')); + $output .= $element['#description'] ? '<div class="description">'. $element['#description'] .'</div>' : ''; + $output .= drupal_render($element[$element['#field_name'] .'_add_more']); + + drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class); + } + else { + foreach (element_children($element) as $key) { + $output .= drupal_render($element[$key]); + } + } + + return $output; +} + +/** + * Modules notify Content module when uninstalled, disabled, etc. + * + * @param string $op + * the module operation: uninstall, install, enable, disable + * @param string $module + * the name of the affected module. + * @TODO + * figure out exactly what needs to be done by content module when + * field modules are installed, uninstalled, enabled or disabled. + */ +function content_notify($op, $module) { + switch ($op) { + case 'install': + content_clear_type_cache(); + break; + case 'uninstall': + module_load_include('inc', 'content', 'includes/content.crud'); + content_module_delete($module); + break; + case 'enable': + content_associate_fields($module); + content_clear_type_cache(); + break; + case 'disable': + // When CCK modules are disabled before content module's update is run + // to add the active column, we can't do this. + if (variable_get('content_schema_version', -1) < 6007) { + return FALSE; + } + db_query("UPDATE {". content_field_tablename() ."} SET active=0 WHERE module='%s'", $module); + db_query("UPDATE {". content_instance_tablename() ."} SET widget_active=0 WHERE widget_module='%s'", $module); + content_clear_type_cache(TRUE); + break; + } +} + +/** + * Allows a module to update the database for fields and columns it controls. + * + * @param string $module + * The name of the module to update on. + */ +function content_associate_fields($module) { + // When CCK modules are enabled before content module's update is run, + // to add module and active columns, we can't do this. + if (variable_get('content_schema_version', -1) < 6007) { + return FALSE; + } + $module_fields = module_invoke($module, 'field_info'); + if ($module_fields) { + foreach ($module_fields as $name => $field_info) { + watchdog('content', 'Updating field type %type with module %module.', array('%type' => $name, '%module' => $module)); + db_query("UPDATE {". content_field_tablename() ."} SET module = '%s', active = %d WHERE type = '%s'", $module, 1, $name); + } + } + $module_widgets = module_invoke($module, 'widget_info'); + if ($module_widgets) { + foreach ($module_widgets as $name => $widget_info) { + watchdog('content', 'Updating widget type %type with module %module.', array('%type' => $name, '%module' => $module)); + db_query("UPDATE {". content_instance_tablename() ."} SET widget_module = '%s', widget_active = %d WHERE widget_type = '%s'", $module, 1, $name); + } + } + // This is called from updates and installs, so get the install-safe + // version of a fields array. + $fields_set = array(); + module_load_include('install', 'content'); + $types = content_types_install(); + foreach ($types as $type_name => $fields) { + foreach ($fields as $field) { + if ($field['module'] == $module && !in_array($field['field_name'], $fields_set)) { + $columns = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field); + db_query("UPDATE {". content_field_tablename() ."} SET db_columns = '%s' WHERE field_name = '%s'", serialize($columns), $field['field_name']); + $fields_set[] = $field['field_name']; + } + } + } +} + +/** + * Implementation of hook_field(). Handles common field housekeeping. + * + * This implementation is special, as content.module does not define any field + * types. Instead, this function gets called after the type-specific hook, and + * takes care of default stuff common to all field types. + * + * Db-storage ops ('load', 'insert', 'update', 'delete', 'delete revisions') + * are not executed field by field, and are thus handled separately in + * content_storage. + * + * The 'view' operation constructs the $node in a way that you can use + * drupal_render() to display the formatted output for an individual field. + * i.e. print drupal_render($node->countent['field_foo']); + * + * The code now supports both single value formatters, which theme an + * individual item value as has been done in previous version of CCK, + * and multiple value formatters, which theme all values for the field + * in a single theme. The multiple value formatters could be used, for + * instance, to plot field values on a single map or display them + * in a graph. Single value formatters are the default, multiple value + * formatters can be designated as such in formatter_info(). + * + * The node array will look like: + * $node->content['field_foo']['wrapper'] = array( + * '#type' => 'content_field', + * '#title' => 'label' + * '#field_name' => 'field_name', + * '#node' => $node, + * // Value of the $teaser param of hook_nodeapi('view'). + * '#teaser' => $teaser, + * // Value of the $page param of hook_nodeapi('view'). + * '#page' => $page, + * // The curent rendering context ('teaser', 'full', NODE_BUILD_SEARCH_INDEX...). + * '#context' => $context, + * 'items' => + * 0 => array( + * '#item' => $items[0], + * // Only for 'single-value' formatters + * '#theme' => $theme, + * '#field_name' => 'field_name', + * '#type_name' => $node->type, + * '#formatter' => $formatter_name, + * '#node' => $node, + * '#delta' => 0, + * ), + * 1 => array( + * '#item' => $items[1], + * // Only for 'single-value' formatters + * '#theme' => $theme, + * '#field_name' => 'field_name', + * '#type_name' => $node->type, + * '#formatter' => $formatter_name, + * '#node' => $node, + * '#delta' => 1, + * ), + * // Only for 'multiple-value' formatters + * '#theme' => $theme, + * '#field_name' => 'field_name', + * '#type_name' => $node->type, + * '#formatter' => $formatter_name, + * ), + * ); + */ +function content_field($op, &$node, $field, &$items, $teaser, $page) { + switch ($op) { + case 'validate': + // TODO: here we could validate that the number of multiple data is correct ? + // We're controlling the number of fields to fill out and saving empty + // ones if a specified number is requested, so no reason to do any validation + // here right now, but if later create a method to indicate whether + // 'required' means all values must be filled out, we can come back + // here and check that they're not empty. + break; + + case 'presave': + if (!empty($node->devel_generate)) { + include_once('./'. drupal_get_path('module', 'content') .'/includes/content.devel.inc'); + content_generate_fields($node, $field); + $items = $node->{$field['field_name']}; + } + + // Manual node_save calls might not have all fields filled in. + // On node insert, we need to make sure all tables get at least an empty + // record, or subsequent edits, using drupal_write_record() in update mode, + // won't insert any data. + // Missing fields on node update are handled in content_storage(). + if (empty($items) && !isset($node->nid)) { + foreach (array_keys($field['columns']) as $column) { + $items[0][$column] = NULL; + } + $node->$field['field_name'] = $items; + } + + // If there was an AHAH add more button in this field, don't save it. + // TODO: is it still needed ? + unset($items[$field['field_name'] .'_add_more']); + + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) { + // Reorder items to account for drag-n-drop reordering. + $items = _content_sort_items($field, $items); + } + + // Filter out empty values. + $items = content_set_empty($field, $items); + + break; + + case 'view': + $addition = array(); + + // Previewed nodes bypass the 'presave' op, so we need to some massaging. + if ($node->build_mode == NODE_BUILD_PREVIEW && content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) { + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) { + // Reorder items to account for drag-n-drop reordering. + $items = _content_sort_items($field, $items); + } + + // Filter out empty values. + $items = content_set_empty($field, $items); + } + + // NODE_BUILD_NORMAL is 0, and ('whatever' == 0) is TRUE, so we need a ===. + if ($node->build_mode === NODE_BUILD_NORMAL || $node->build_mode == NODE_BUILD_PREVIEW) { + $context = $teaser ? 'teaser' : 'full'; + } + else { + $context = $node->build_mode; + } + // The field may be missing info for $contexts added by modules + // enabled after the field was last edited. + $formatter_name = isset($field['display_settings'][$context]) && isset($field['display_settings'][$context]['format']) ? $field['display_settings'][$context]['format'] : 'default'; + if ($formatter = _content_get_formatter($formatter_name, $field['type'])) { + $theme = $formatter['module'] .'_formatter_'. $formatter_name; + $single = (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE); + + $label_display = isset($field['display_settings']['label']['format']) ? $field['display_settings']['label']['format'] : 'above'; + // Do not include field labels when indexing content. + if ($context == NODE_BUILD_SEARCH_INDEX) { + $label_display = 'hidden'; + } + + $element = array( + '#type' => 'content_field', + '#title' => check_plain(t($field['widget']['label'])), + '#field_name' => $field['field_name'], + '#access' => $formatter_name != 'hidden' && content_access('view', $field, NULL, $node), + '#label_display' => $label_display, + '#node' => $node, + '#teaser' => $teaser, + '#page' => $page, + '#context' => $context, + '#single' => $single, + 'items' => array(), + ); + + // Fill-in items. + foreach ($items as $delta => $item) { + $element['items'][$delta] = array( + '#item' => $item, + '#weight' => $delta, + ); + } + + // Append formatter information either on each item ('single-value' formatter) + // or at the upper 'items' level ('multiple-value' formatter) + $format_info = array( + '#theme' => $theme, + '#field_name' => $field['field_name'], + '#type_name' => $node->type, + '#formatter' => $formatter_name, + '#node' => $node, + ); + if ($single) { + foreach ($items as $delta => $item) { + $element['items'][$delta] += $format_info; + $element['items'][$delta]['#item']['#delta'] = $delta; + } + } + else { + $element['items'] += $format_info; + } + + // The wrapper lets us get the themed output for the whole field + // to populate the $FIELD_NAME_rendered variable for node templates, + // and hide it from the $content variable if needed. + // See 'preprocess_node' op and theme_content_field_wrapper()? + $wrapper = array( + 'field' => $element, + '#weight' => $field['widget']['weight'], + '#post_render' => array('content_field_wrapper_post_render'), + '#field_name' => $field['field_name'], + '#type_name' => $node->type, + '#context' => $context, + ); + + $addition = array($field['field_name'] => $wrapper); + } + return $addition; + + case 'alter': + // Add back the formatted values in the 'view' element, + // so that tokens and node templates can use it. + // Note: Doing this in 'preprocess_node' breaks token integration. + + // The location of the field's rendered output depends on whether the + // field is in a fieldgroup or not. + $wrapper = NULL; + if (isset($node->content[$field['field_name']])) { + $wrapper = $node->content[$field['field_name']]; + } + elseif (module_exists('fieldgroup') && ($group_name = fieldgroup_get_group($node->type, $field['field_name'])) && isset($node->content[$group_name]['group'][$field['field_name']])) { + $wrapper = $node->content[$group_name]['group'][$field['field_name']]; + } + + if ($wrapper) { + $element = $wrapper['field']; + // '#single' is not set if the field is hidden or inaccessible. + if (isset($element['#single'])) { + if (!empty($element['#single'])) { + // Single value formatter. + foreach (element_children($element['items']) as $delta) { + // '#chilren' is not set if the field is empty. + $items[$delta]['view'] = isset($element['items'][$delta]['#children']) ? $element['items'][$delta]['#children'] : ''; + } + } + elseif (isset($element['items']['#children'])) { + // Multiple values formatter. + $items[0]['view'] = $element['items']['#children']; + } + } + else { + // Hidden or inaccessible field. + $items[0]['view'] = ''; + } + } + break; + + case 'preprocess_node': + // Add $FIELD_NAME_rendered variables. + $addition = array(); + + // The location of the field's rendered output depends on whether the + // field is in a fieldgroup or not. + $wrapper = NULL; + if (isset($node->content[$field['field_name']])) { + $wrapper = $node->content[$field['field_name']]; + } + elseif (module_exists('fieldgroup') && ($group_name = fieldgroup_get_group($node->type, $field['field_name'])) && isset($node->content[$group_name]['group'][$field['field_name']])) { + $wrapper = $node->content[$group_name]['group'][$field['field_name']]; + } + + if ($wrapper) { + // '#chilren' is not set if the field is empty. + $addition[$field['field_name'] .'_rendered'] = isset($wrapper['#children']) ? $wrapper['#children'] : ''; + } + + return $addition; + + case 'prepare translation': + $addition = array(); + if (isset($node->translation_source->$field['field_name'])) { + $addition[$field['field_name']] = $node->translation_source->$field['field_name']; + } + return $addition; + } +} + +/** + * Helper function to filter out empty values. + * + * On order to keep marker rows in the database, the function ensures + * that the right number of 'all columns NULL' values is kept. + * + * @param array $field + * @param array $items + * @return array + * returns filtered and adjusted item array + */ +function content_set_empty($field, $items) { + // Filter out empty values. + $filtered = array(); + $function = $field['module'] .'_content_is_empty'; + foreach ((array) $items as $delta => $item) { + if (!$function($item, $field)) { + $filtered[] = $item; + } + } + + // Make sure we store the right number of 'empty' values. + $empty = array(); + foreach (array_keys($field['columns']) as $column) { + $empty[$column] = NULL; + } + $pad = $field['multiple'] > 1 ? $field['multiple'] : 1; + $filtered = array_pad($filtered, $pad, $empty); + + return $filtered; +} + +/** + * Helper function to sort items in a field according to + * user drag-n-drop reordering. + */ +function _content_sort_items($field, $items) { + if ($field['multiple'] >= 1 && isset($items[0]['_weight'])) { + usort($items, '_content_sort_items_helper'); + foreach ($items as $delta => $item) { + if (is_array($items[$delta])) { + unset($items[$delta]['_weight']); + } + } + } + return $items; +} + +/** + * Sort function for items order. + * (copied form element_sort(), which acts on #weight keys) + */ +function _content_sort_items_helper($a, $b) { + $a_weight = (is_array($a) && isset($a['_weight'])) ? $a['_weight'] : 0; + $b_weight = (is_array($b) && isset($b['_weight'])) ? $b['_weight'] : 0; + if ($a_weight == $b_weight) { + return 0; + } + return ($a_weight < $b_weight) ? -1 : 1; +} + +/** + * Same as above, using ['_weight']['#value'] + */ +function _content_sort_items_value_helper($a, $b) { + $a_weight = (is_array($a) && isset($a['_weight']['#value'])) ? $a['_weight']['#value'] : 0; + $b_weight = (is_array($b) && isset($b['_weight']['#value'])) ? $b['_weight']['#value'] : 0; + if ($a_weight == $b_weight) { + return 0; + } + return ($a_weight < $b_weight) ? -1 : 1; +} + +/** + * Handle storage ops for _content_field_invoke_default(). + */ +function content_storage($op, $node) { + // Don't try this before content module's update is run to add + // the active and module columns. + if (variable_get('content_schema_version', -1) < 6007) { + return FALSE; + } + + $type_name = $node->type; + $type = content_types($type_name); + + switch ($op) { + case 'load': + // OPTIMIZE: load all non multiple fields in a single JOIN query ? + // warning: 61-join limit in MySQL ? + $additions = array(); + // For each table used by this content type, + foreach ($type['tables'] as $table) { + $schema = drupal_get_schema($table); + // The per-type table might not have any fields actually stored in it. + if (!$schema['content fields']) { + continue; + } + $query = 'SELECT * FROM {'. $table .'} WHERE vid = %d'; + + // If we're loading a table for a multiple field, + // we fetch all rows (values) ordered by delta, + // else we only fetch one row. + $result = isset($schema['fields']['delta']) ? db_query($query .' ORDER BY delta', $node->vid) : db_query_range($query, $node->vid, 0, 1); + + // For each table row, populate the fields. + while ($row = db_fetch_array($result)) { + // For each field stored in the table, add the field item. + foreach ($schema['content fields'] as $field_name) { + $item = array(); + $field = content_fields($field_name, $type_name); + $db_info = content_database_info($field); + // For each column declared by the field, populate the item. + foreach ($db_info['columns'] as $column => $attributes) { + $item[$column] = $row[$attributes['column']]; + } + + // Add the item to the field values for the node. + if (!isset($additions[$field_name])) { + $additions[$field_name] = array(); + } + $additions[$field_name][] = $item; + } + } + } + return $additions; + + case 'insert': + case 'update': + foreach ($type['tables'] as $table) { + $schema = drupal_get_schema($table); + $record = array(); + foreach ($schema['content fields'] as $field_name) { + if (isset($node->$field_name)) { + $field = content_fields($field_name, $type_name); + // Multiple fields need specific handling, we'll deal with them later on. + if ($field['multiple']) { + continue; + } + $db_info = content_database_info($field); + foreach ($db_info['columns'] as $column => $attributes) { + $record[$attributes['column']] = $node->{$field_name}[0][$column]; + } + } + } + // $record might be empty because + // - the table stores a multiple field : + // we do nothing, this is handled later on + // - this is the per-type table and no field is actually stored in it : + // we still store the nid and vid + if (count($record) || empty($schema['content fields'])) { + $record['nid'] = $node->nid; + $record['vid'] = $node->vid; + // Can't rely on the insert/update op of the node to decide if this + // is an insert or an update, a node or revision may have existed + // before any fields were created, so there may not be an entry here. + + // TODO - should we auto create an entry for all existing nodes when + // fields are added to content types -- either a NULL value + // or the default value? May need to offer the user an option of + // how to handle that. + if (db_result(db_query("SELECT COUNT(*) FROM {". $table ."} WHERE vid = %d", $node->vid))) { + content_write_record($table, $record, array('vid')); + } + else { + content_write_record($table, $record); + } + } + } + + // Handle multiple fields. + foreach ($type['fields'] as $field) { + if ($field['multiple'] && isset($node->$field['field_name'])) { + $db_info = content_database_info($field); + // Delete and insert, rather than update, in case a value was added. + if ($op == 'update') { + db_query('DELETE FROM {'. $db_info['table'] .'} WHERE vid = %d', $node->vid); + } + foreach ($node->$field['field_name'] as $delta => $item) { + $record = array(); + foreach ($db_info['columns'] as $column => $attributes) { + $record[$attributes['column']] = $item[$column]; + } + $record['nid'] = $node->nid; + $record['vid'] = $node->vid; + $record['delta'] = $delta; + content_write_record($db_info['table'], $record); + } + } + } + break; + + case 'delete': + foreach ($type['tables'] as $table) { + db_query('DELETE FROM {'. $table .'} WHERE nid = %d', $node->nid); + } + break; + + case 'delete revision': + foreach ($type['tables'] as $table) { + db_query('DELETE FROM {'. $table .'} WHERE vid = %d', $node->vid); + } + break; + } +} + +/** + * Save a record to the database based upon the schema. + * + * Directly copied from core's drupal_write_record, which can't update a + * column to NULL. See http://drupal.org/node/227677 and + * http://drupal.org/node/226264 for more details about that problem. + * + * TODO - get rid of this function and change references back to + * drupal_write_record() if the patch gets into core. Will need a method + * of protecting people on older versions, though. + * + * Default values are filled in for missing items, and 'serial' (auto increment) + * types are filled in with IDs. + * + * @param $table + * The name of the table; this must exist in schema API. + * @param $object + * The object to write. This is a reference, as defaults according to + * the schema may be filled in on the object, as well as ID on the serial + * type(s). Both array an object types may be passed. + * @param $update + * If this is an update, specify the primary keys' field names. It is the + * caller's responsibility to know if a record for this object already + * exists in the database. If there is only 1 key, you may pass a simple string. + * @return + * Failure to write a record will return FALSE. Otherwise SAVED_NEW or + * SAVED_UPDATED is returned depending on the operation performed. The + * $object parameter contains values for any serial fields defined by + * the $table. For example, $object->nid will be populated after inserting + * a new node. + */ +function content_write_record($table, &$object, $update = array()) { + // Standardize $update to an array. + if (is_string($update)) { + $update = array($update); + } + + // Convert to an object if needed. + if (is_array($object)) { + $object = (object) $object; + $array = TRUE; + } + else { + $array = FALSE; + } + + $schema = drupal_get_schema($table); + if (empty($schema)) { + return FALSE; + } + + $fields = $defs = $values = $serials = $placeholders = array(); + + // Go through our schema, build SQL, and when inserting, fill in defaults for + // fields that are not set. + foreach ($schema['fields'] as $field => $info) { + // Special case -- skip serial types if we are updating. + if ($info['type'] == 'serial' && count($update)) { + continue; + } + + // For inserts, populate defaults from Schema if not already provided + if (!isset($object->$field) && !count($update) && isset($info['default'])) { + $object->$field = $info['default']; + } + + // Track serial fields so we can helpfully populate them after the query. + if ($info['type'] == 'serial') { + $serials[] = $field; + // Ignore values for serials when inserting data. Unsupported. + unset($object->$field); + } + + // Build arrays for the fields, placeholders, and values in our query. + if (isset($object->$field) || array_key_exists($field, $object)) { + $fields[] = $field; + if (isset($object->$field)) { + $placeholders[] = db_type_placeholder($info['type']); + + if (empty($info['serialize'])) { + $values[] = $object->$field; + } + else { + $values[] = serialize($object->$field); + } + } + else { + $placeholders[] = 'NULL'; + } + } + } + + // Build the SQL. + $query = ''; + if (!count($update)) { + $query = "INSERT INTO {". $table ."} (". implode(', ', $fields) .') VALUES ('. implode(', ', $placeholders) .')'; + $return = SAVED_NEW; + } + else { + $query = ''; + foreach ($fields as $id => $field) { + if ($query) { + $query .= ', '; + } + $query .= $field .' = '. $placeholders[$id]; + } + + foreach ($update as $key) { + $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']); + $values[] = $object->$key; + } + + $query = "UPDATE {". $table ."} SET $query WHERE ". implode(' AND ', $conditions); + $return = SAVED_UPDATED; + } + + // Execute the SQL. + if (db_query($query, $values)) { + if ($serials) { + // Get last insert ids and fill them in. + foreach ($serials as $field) { + $object->$field = db_last_insert_id($table, $field); + } + } + + // If we began with an array, convert back so we don't surprise the caller. + if ($array) { + $object = (array) $object; + } + + return $return; + } + + return FALSE; +} + +/** + * Invoke a field hook. + * + * For each operation, both this function and _content_field_invoke_default() are + * called so that the default database handling can occur. + */ +function _content_field_invoke($op, &$node, $teaser = NULL, $page = NULL) { + $type_name = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type); + $type = content_types($type_name); + $field_types = _content_field_types(); + + $return = array(); + foreach ($type['fields'] as $field) { + $items = isset($node->$field['field_name']) ? $node->$field['field_name'] : array(); + + // Make sure AHAH 'add more' button isn't sent to the fields for processing. + unset($items[$field['field_name'] .'_add_more']); + + $module = $field_types[$field['type']]['module']; + $function = $module .'_field'; + if (function_exists($function)) { + $result = $function($op, $node, $field, $items, $teaser, $page); + if (is_array($result)) { + $return = array_merge($return, $result); + } + else if (isset($result)) { + $return[] = $result; + } + } + // test for values in $items in case modules added items on insert + if (isset($node->$field['field_name']) || count($items)) { + $node->$field['field_name'] = $items; + } + } + return $return; +} + +/** + * Invoke content.module's version of a field hook. + */ +function _content_field_invoke_default($op, &$node, $teaser = NULL, $page = NULL) { + $type_name = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type); + $type = content_types($type_name); + $field_types = _content_field_types(); + + $return = array(); + // The operations involving database queries are better off handled by table + // rather than by field. + if (in_array($op, array('load', 'insert', 'update', 'delete', 'delete revision'))) { + return content_storage($op, $node); + } + else { + foreach ($type['fields'] as $field) { + $items = isset($node->$field['field_name']) ? $node->$field['field_name'] : array(); + $result = content_field($op, $node, $field, $items, $teaser, $page); + if (is_array($result)) { + $return = array_merge($return, $result); + } + else if (isset($result)) { + $return[] = $result; + } + if (isset($node->$field['field_name'])) { + $node->$field['field_name'] = $items; + } + } + } + return $return; +} + +/** + * Return a list of all content types. + * + * @param $content_type_name + * If set, return information on just this type. + * + * Do some type checking and set up empty arrays for missing + * info to avoid foreach errors elsewhere in the code. + */ +function content_types($type_name = NULL) { + // handle type name with either an underscore or a dash + $type_name = !empty($type_name) ? str_replace('-', '_', $type_name) : NULL; + + $info = _content_type_info(); + if (isset($info['content types'])) { + if (!isset($type_name)) { + return $info['content types']; + } + if (isset($info['content types'][$type_name])) { + return $info['content types'][$type_name]; + } + } + return array('tables' => array(), 'fields' => array(), 'extra' => array()); +} + +/** + * Return a list of all fields. + * + * @param $field_name + * If not empty, return information on just this field. + * @param $content_type_name + * If not empty, return information of the field within the context of this content + * type. + * + * Be sure to check empty() instead of isset() on field_name and + * content_type_name to avoid bad results when the value is set + * but empty, as sometimes happens in the formatter. + */ +function content_fields($field_name = NULL, $content_type_name = NULL) { + $info = _content_type_info(); + if (isset($info['fields'])) { + if (empty($field_name)) { + return $info['fields']; + } + if (isset($info['fields'][$field_name])) { + if (empty($content_type_name)) { + return $info['fields'][$field_name]; + } + if (isset($info['content types'][$content_type_name]['fields'][$field_name])) { + return $info['content types'][$content_type_name]['fields'][$field_name]; + } + } + } +} + +/** + * Return a list of field types. + */ +function _content_field_types() { + $info = _content_type_info(); + return isset($info['field types']) ? $info['field types'] : array(); +} + +/** + * Return a list of widget types. + */ +function _content_widget_types() { + $info = _content_type_info(); + return isset($info['widget types']) ? $info['widget types'] : array(); +} + +/** + * Return the formatter description corresponding to a formatter name, + * defaulting to 'default' if none is found. + */ +function _content_get_formatter($formatter_name, $field_type) { + $field_types = _content_field_types(); + $formatters = $field_types[$field_type]['formatters']; + + if (!isset($formatters[$formatter_name]) && $formatter_name != 'hidden') { + // This might happen when the selected formatter has been renamed in the + // module, or if the module has been disabled since then. + $formatter_name = 'default'; + } + + return isset($formatters[$formatter_name]) ? $formatters[$formatter_name] : FALSE; +} + +/** + * Collate all information on content types, fields, and related structures. + * + * @param $reset + * If TRUE, clear the cache and fetch the information from the database again. + */ +function _content_type_info($reset = FALSE) { + global $language; + static $info; + + if ($reset || !isset($info)) { + // Make sure this function doesn't run until the tables have been created, + // For instance: when first enabled and called from content_menu(), + // or when uninstalled and some subsequent field module uninstall + // attempts to refresh the data. + + // Don't try this before content module's update is run + // to add module and active columns to the table. + if (variable_get('content_schema_version', -1) < 6007) { + return array(); + } + + if (!$reset && $cached = cache_get('content_type_info:'. $language->language, content_cache_tablename())) { + $info = $cached->data; + } + else { + $info = array( + 'field types' => array(), + 'widget types' => array(), + 'fields' => array(), + 'content types' => array(), + ); + + // Populate field types. + foreach (module_list() as $module) { + $module_field_types = module_invoke($module, 'field_info'); + if ($module_field_types) { + foreach ($module_field_types as $name => $field_info) { + // Truncate names to match the value that is stored in the database. + $db_name = substr($name, 0, 32); + $info['field types'][$db_name] = $field_info; + $info['field types'][$db_name]['module'] = $module; + $info['field types'][$db_name]['formatters'] = array(); + } + } + } + + // Populate widget types and formatters for known field types. + foreach (module_list() as $module) { + if ($module_widgets = module_invoke($module, 'widget_info')) { + foreach ($module_widgets as $name => $widget_info) { + // Truncate names to match the value that is stored in the database. + $db_name = substr($name, 0, 32); + $info['widget types'][$db_name] = $widget_info; + $info['widget types'][$db_name]['module'] = $module; + // Replace field types with db_compatible version of known field types. + $info['widget types'][$db_name]['field types'] = array(); + foreach ($widget_info['field types'] as $field_type) { + $field_type_db_name = substr($field_type, 0, 32); + if (isset($info['field types'][$field_type_db_name])) { + $info['widget types'][$db_name]['field types'][] = $field_type_db_name; + } + } + } + } + + if ($module_formatters = module_invoke($module, 'field_formatter_info')) { + foreach ($module_formatters as $name => $formatter_info) { + foreach ($formatter_info['field types'] as $field_type) { + // Truncate names to match the value that is stored in the database. + $db_name = substr($field_type, 0, 32); + if (isset($info['field types'][$db_name])) { + $info['field types'][$db_name]['formatters'][$name] = $formatter_info; + $info['field types'][$db_name]['formatters'][$name]['module'] = $module; + } + } + } + } + } + + // Populate actual field instances. + module_load_include('inc', 'content', 'includes/content.crud'); + foreach (node_get_types('types', NULL, TRUE) as $type_name => $data) { + $type = (array) $data; + $type['url_str'] = str_replace('_', '-', $type['type']); + $type['fields'] = array(); + $type['tables'] = array(); + if ($fields = content_field_instance_read(array('type_name' => $type_name))) { + foreach ($fields as $field) { + $db_info = content_database_info($field); + $type['tables'][$db_info['table']] = $db_info['table']; + + // Allow external modules to translate field strings. + $field_strings = array( + 'widget_label' => $field['widget']['label'], + 'widget_description' => $field['widget']['description'], + ); + drupal_alter('content_field_strings', $field_strings, $field['type_name'], $field['field_name']); + $field['widget']['label'] = $field_strings['widget_label']; + $field['widget']['description'] = $field_strings['widget_description']; + + $type['fields'][$field['field_name']] = $field; + // This means that content_fields($field_name) (no type name) + // returns the last instance loaded. + $info['fields'][$field['field_name']] = $field; + } + // Make sure the per-type table is added, even if no field is actually + // stored in it. + $table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + $type['tables'][$table] = $table; + } + + // Gather information about non-CCK 'fields'. + $extra = module_invoke_all('content_extra_fields', $type_name); + drupal_alter('content_extra_fields', $extra, $type_name); + // Add saved weights. + foreach (variable_get('content_extra_weights_'. $type_name, array()) as $key => $value) { + // Some stored entries might not exist anymore, for instance if uploads + // have been disabled, or vocabularies removed... + if (isset($extra[$key])) { + $extra[$key]['weight'] = $value; + } + } + $type['extra'] = $extra; + + $info['content types'][$type_name] = $type; + } + + cache_set('content_type_info:'. $language->language, $info, content_cache_tablename()); + } + } + return $info; +} + +/** + * Implementation of hook_node_type() + * React to change in node types + */ +function content_node_type($op, $info) { + switch ($op) { + case 'insert': + module_load_include('inc', 'content', 'includes/content.crud'); + content_type_create($info); + break; + case 'update': + module_load_include('inc', 'content', 'includes/content.crud'); + content_type_update($info); + break; + case 'delete': + module_load_include('inc', 'content', 'includes/content.crud'); + content_type_delete($info); + break; + } +} + +/** + * Clear the cache of content_types; called in several places when content + * information is changed. + */ +function content_clear_type_cache($rebuild_schema = FALSE) { + cache_clear_all('*', content_cache_tablename(), TRUE); + _content_type_info(TRUE); + + // Refresh the schema to pick up new information. + if ($rebuild_schema) { + $schema = drupal_get_schema(NULL, TRUE); + } + + if (module_exists('views')) { + // Needed because this can be called from .install files + module_load_include('module', 'views'); + views_invalidate_cache(); + } +} + +/** + * Retrieve the database storage location(s) for a field. + * + * TODO: add a word about why it's not included in the global _content_type_info array. + * + * @param $field + * The field whose database information is requested. + * @return + * An array with the keys: + * "table": The name of the database table where the field data is stored. + * "columns": An array of columns stored for this field. Each is a collection + * of information returned from hook_field_settings('database columns'), + * with the addition of a "column" attribute which holds the name of the + * database column that stores the data. + */ +function content_database_info($field) { + $db_info = array(); + if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) { + $db_info['table'] = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD); + } + else { + $db_info['table'] = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + } + + $db_info['columns'] = (array) $field['columns']; + // Generate column names for this field from generic column names. + foreach ($db_info['columns'] as $column_name => $attributes) { + $db_info['columns'][$column_name]['column'] = $field['field_name'] .'_'. $column_name; + } + + return $db_info; +} + +/** + * Helper function for identifying the storage type for a field. + */ +function content_storage_type($field) { + if ($field['multiple'] > 0) { + return CONTENT_DB_STORAGE_PER_FIELD; + } + else { + module_load_include('inc', 'content', 'includes/content.crud'); + $instances = content_field_instance_read(array('field_name' => $field['field_name'])); + if (count($instances) > 1) { + return CONTENT_DB_STORAGE_PER_FIELD; + } + } + return CONTENT_DB_STORAGE_PER_CONTENT_TYPE; +} + +/** + * Manipulate a 2D array to reverse rows and columns. + * + * The default data storage for fields is delta first, column names second. + * This is sometimes inconvenient for field modules, so this function can be + * used to present the data in an alternate format. + * + * @param $array + * The array to be transposed. It must be at least two-dimensional, and + * the subarrays must all have the same keys or behavior is undefined. + * @return + * The transposed array. + */ +function content_transpose_array_rows_cols($array) { + $result = array(); + if (is_array($array)) { + foreach ($array as $key1 => $value1) { + if (is_array($value1)) { + foreach ($value1 as $key2 => $value2) { + if (!isset($result[$key2])) { + $result[$key2] = array(); + } + $result[$key2][$key1] = $value2; + } + } + } + } + return $result; +} + +/** + * Helper function to flatten an array of allowed values. + * + * @param $array + * A single or multidimensional array. + * @return + * A flattened array. + */ +function content_array_flatten($array) { + $result = array(); + if (is_array($array)) { + foreach ($array as $key => $value) { + if (is_array($value)) { + $result += content_array_flatten($value); + } + else { + $result[$key] = $value; + } + } + } + return $result; +} + +/** + * Create an array of the allowed values for this field. + * + * Used by number and text fields, expects to find either + * PHP code that will return the correct value, or a string + * with keys and labels separated with '|' and with each + * new value on its own line. + * + * @param $field + * The field whose allowed values are requested. + * @param $flatten + * Optional. Use TRUE to return a flattened array (default). + * FALSE can be used to support optgroups for select widgets + * when allowed values list is generated using PHP code. + */ +function content_allowed_values($field, $flatten = TRUE) { + static $allowed_values; + + $cid = $field['field_name'] .':'. ($flatten ? '1' : '0'); + if (isset($allowed_values[$cid])) { + return $allowed_values[$cid]; + } + + $allowed_values[$cid] = array(); + + if (isset($field['allowed_values_php'])) { + ob_start(); + $result = eval($field['allowed_values_php']); + if (is_array($result)) { + if ($flatten) { + $result = content_array_flatten($result); + } + $allowed_values[$cid] = $result; + } + ob_end_clean(); + } + + if (empty($allowed_values[$cid]) && isset($field['allowed_values'])) { + $list = explode("\n", $field['allowed_values']); + $list = array_map('trim', $list); + $list = array_filter($list, 'strlen'); + foreach ($list as $opt) { + // Sanitize the user input with a permissive filter. + $opt = content_filter_xss($opt); + if (strpos($opt, '|') !== FALSE) { + list($key, $value) = explode('|', $opt); + $allowed_values[$cid][$key] = (isset($value) && $value !=='') ? $value : $key; + } + else { + $allowed_values[$cid][$opt] = $opt; + } + } + // Allow external modules to translate allowed values list. + drupal_alter('content_allowed_values', $allowed_values[$cid], $field); + } + return $allowed_values[$cid]; +} + +/** + * Filter out HTML from allowed values array while leaving entities unencoded. + * + * @see content_allowed_values() + * @see optionwidgets_select_process() + * @see content_handler_filter_many_to_one::allowed_values() + */ +function content_allowed_values_filter_html(&$options) { + foreach ($options as $key => $opt) { + if (is_array($opt)) { + content_allowed_values_filter_html($options[$key]); + } + else { + $options[$key] = html_entity_decode(strip_tags($opt), ENT_QUOTES); + } + } +} + +/** + * Like filter_xss_admin(), but with a shorter list of allowed tags. + * + * Used for items entered by administrators, like field descriptions, + * allowed values, where some (mainly inline) mark-up may be desired + * (so check_plain() is not acceptable). + */ +function content_filter_xss($string) { + return filter_xss($string, _content_filter_xss_allowed_tags()); +} + +/** + * List of tags allowed by content_filter_xss(). + */ +function _content_filter_xss_allowed_tags() { + return array('a', 'b', 'big', 'code', 'del', 'em', 'i', 'ins', 'pre', 'q', 'small', 'span', 'strong', 'sub', 'sup', 'tt', 'ol', 'ul', 'li', 'p', 'br', 'img'); +} + +/** + * Human-readable list of allowed tags, for display in help texts. + */ +function _content_filter_xss_display_allowed_tags() { + return '<'. implode('> <', _content_filter_xss_allowed_tags()) .'>'; +} + +/** + * Format a field item for display. + * + * Used to display a field's values outside the context of the $node, as + * when fields are displayed in Views, or to display a field in a template + * using a different formatter than the one set up on the Display Fields tab + * for the node's context. + * + * @param $field + * Either a field array or the name of the field. + * @param $item + * The field item(s) to be formatted (such as $node->field_foo[0], + * or $node->field_foo if the formatter handles multiple values itself) + * @param $formatter_name + * The name of the formatter to use. + * @param $node + * Optionally, the containing node object for context purposes and + * field-instance options. + * + * @return + * A string containing the contents of the field item(s) sanitized for display. + * It will have been passed through the necessary check_plain() or check_markup() + * functions as necessary. + */ +function content_format($field, $item, $formatter_name = 'default', $node = NULL) { + if (!is_array($field)) { + $field = content_fields($field); + } + + if (content_access('view', $field, NULL, $node) && $formatter = _content_get_formatter($formatter_name, $field['type'])) { + $theme = $formatter['module'] .'_formatter_'. $formatter_name; + + $element = array( + '#theme' => $theme, + '#field_name' => $field['field_name'], + '#type_name' => isset($node->type) ? $node->type :'', + '#formatter' => $formatter_name, + '#node' => $node, + '#delta' => isset($item['#delta']) ? $item['#delta'] : NULL, + ); + + if (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE) { + // Single value formatter. + + // hook_field('sanitize') expects an array of items, so we build one. + $items = array($item); + $function = $field['module'] .'_field'; + if (function_exists($function)) { + $function('sanitize', $node, $field, $items, FALSE, FALSE); + } + + $element['#item'] = $items[0]; + } + else { + // Multiple values formatter. + $items = $item; + $function = $field['module'] .'_field'; + if (function_exists($function)) { + $function('sanitize', $node, $field, $items, FALSE, FALSE); + } + + foreach ($items as $delta => $item) { + $element[$delta] = array( + '#item' => $item, + '#weight' => $delta, + ); + } + } + + return theme($theme, $element); + } +} + +/** + * Registry of available node build modes. + * + * @param $selector + * Determines what information should be returned. + * @return + * Depending on the value of the $selector parameter: + * - NULL: a flat list of all available build modes. + * The other two options are mainly used internally by CCK's UI: + * - '_tabs': the list of tabs to be shown on the 'Display fields' screens. + * - a string tab id: the build modes in this tab. + */ +function content_build_modes($selector = NULL) { + static $info; + + if (!isset($info)) { + $data = array(); + foreach (module_implements('content_build_modes') as $module) { + $function = $module .'_content_build_modes'; + $data = array_merge($data, (array) $function()); + } + $flat = array(); + foreach ($data as $tab) { + // Use the + operator to preserve numeric indexes (core build modes). + $flat += (array) $tab['build modes']; + } + $info = array('tabs' => $data, 'build modes' => $flat); + } + + if ($selector === '_tabs') { + return $info['tabs']; + } + elseif (isset($selector) && isset($info['tabs'][$selector])) { + return isset($info['tabs'][$selector]) ? $info['tabs'][$selector]['build modes'] : array(); + } + else { + return $info['build modes']; + } +} + +/** + * Implementations of hook_content_build_modes + * on behalf of core modules. + * + * @return + * An array describing the build modes used by the module. + * They are grouped by secondary tabs on CCK's 'Display fields' screens. + * + * Expected format: + * array( + * // The first level keys (tab1_url, tab2_url) will be used to generate + * // the url of the tab: admin/content/node-type/[type_name]/display/[tab1_url] + * // A module can add its render modes to a tab defined by another module. + * // In this case, there's no need to provide a 'title' for this tab. + * 'tab1_url' => array( + * 'title' => t('The human-readable title of the tab'), + * 'build modes' => array( + * // The keys of the 'context' array are the values used in $node->build_mode. + * 'mymodule_mode1' => array( + * 'title' => t('The human-readable name of the build mode'), + * // The 'views style' property determines if the render mode should be + * // available as an option in Views' 'node' row style (not implemented yet). + * 'views style' => TRUE, + * ), + * 'mymodule_mode2' => array( + * 'title' => t('Mode 2'), + * 'views style' => TRUE, + * ), + * ), + * ), + * 'tab2_url' => array( + * // ... + * ), + * ); + */ +function node_content_build_modes() { + return array( + 'basic' => array( + 'title' => t('Basic'), + 'build modes' => array( + 'teaser' => array( + 'title' => t('Teaser'), + 'views style' => TRUE, + ), + 'full' => array( + 'title' => t('Full node'), + 'views style' => TRUE, + ), + ), + ), + 'rss' => array( + 'title' => t('RSS'), + 'build modes' => array( + NODE_BUILD_RSS => array( + 'title' => t('RSS'), + 'views style' => FALSE, + ), + ), + ), + ); +} +function search_content_build_modes() { + return array( + 'search' => array( + 'title' => t('Search'), + 'build modes' => array( + NODE_BUILD_SEARCH_INDEX => array( + 'title' => t('Search Index'), + 'views style' => FALSE, + ), + NODE_BUILD_SEARCH_RESULT => array( + 'title' => t('Search Result'), + 'views style' => FALSE, + ), + ), + ), + ); +} +function book_content_build_modes() { + return array( + 'print' => array( + 'title' => t('Print'), + 'build modes' => array( + NODE_BUILD_PRINT => array( + 'title' => t('Print'), + 'views style' => TRUE, + ), + ), + ), + ); +} + +/** + * Generate a table name for a field or a content type. + * + * @param $name + * The name of the content type or content field + * @param $storage + * CONTENT_DB_STORAGE_PER_FIELD or CONTENT_DB_STORAGE_PER_CONTENT_TYPE + * @return + * A string containing the generated name for the database table + */ +function _content_tablename($name, $storage, $version = NULL) { + if (is_null($version)) { + $version = variable_get('content_schema_version', 0); + } + + if ($version < 1003) { + $version = 0; + } + else { + $version = 1003; + } + + $name = str_replace('-', '_', $name); + switch ("$version-$storage") { + case '0-'. CONTENT_DB_STORAGE_PER_CONTENT_TYPE : + return "node_$name"; + case '0-'. CONTENT_DB_STORAGE_PER_FIELD : + return "node_data_$name"; + case '1003-'. CONTENT_DB_STORAGE_PER_CONTENT_TYPE : + return "content_type_$name"; + case '1003-'. CONTENT_DB_STORAGE_PER_FIELD : + return "content_$name"; + } +} + +/** + * Generate table name for the content field table. + * + * Needed because the table name changes depending on version. + * Using 'content_node_field' instead of 'content_field' + * to avoid conflicts with field tables that will be prefixed + * with 'content_field'. + */ +function content_field_tablename($version = NULL) { + if (is_null($version)) { + $version = variable_get('content_schema_version', 0); + } + return $version < 6001 ? 'node_field' : 'content_node_field'; +} + +/** + * Generate table name for the content field instance table. + * + * Needed because the table name changes depending on version. + */ +function content_instance_tablename($version = NULL) { + if (is_null($version)) { + $version = variable_get('content_schema_version', 0); + } + return $version < 6001 ? 'node_field_instance' : 'content_node_field_instance'; +} + +/** + * Generate table name for the content cache table. + * + * Needed because the table name changes depending on version. Because of + * a new database column, the content_cache table will be unusable until + * update 6000 runs, so the cache table will be used instead. + */ +function content_cache_tablename() { + if (variable_get('content_schema_version', -1) < 6000) { + return 'cache'; + } + else { + return 'cache_content'; + } +} + +/** + * A basic schema used by all field and type tables. + * + * This will only add the columns relevant for the specified field. + * Leave $field['columns'] empty to get only the base schema, + * otherwise the function will return the whole thing. + */ +function content_table_schema($field = NULL) { + $schema = array( + 'fields' => array( + 'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0) + ), + 'primary key' => array('vid'), + 'indexes' => array( + 'nid' => array('nid'), + ), + ); + + // Add delta column if needed. + if (!empty($field['multiple'])) { + $schema['fields']['delta'] = array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0); + $schema['primary key'][] = 'delta'; + } + $schema['content fields'] = array(); + + // Add field columns column if needed. + // This function is called from install files where it is not safe + // to use content_fields() or content_database_info(), so we + // just used the column values stored in the $field. + // We also need the schema to include fields from disabled modules + // or there will be no way to delete those fields. + + if (!empty($field['columns'])) { + foreach ($field['columns'] as $column => $attributes) { + $column_name = $field['field_name'] .'_'. $column; + if (isset($attributes['index']) && $attributes['index']) { + $schema['indexes'][$column_name] = array($column_name); + unset($attributes['index']); + } + unset($attributes['column']); + unset($attributes['sortable']); + $schema['fields'][$column_name] = $attributes; + } + $schema['content fields'][] = $field['field_name']; + } + return $schema; +} + +/** + * Checks if an index exists. + * + * @todo: May we remove this funcion when implemented by Drupal core itself? + * @link http://drupal.org/node/360854 + * @link http://dev.mysql.com/doc/refman/5.0/en/extended-show.html + * + * @param $table + * Name of the table. + * @param $name + * Name of the index. + * @return + * TRUE if the table exists. Otherwise FALSE. + */ +function content_db_index_exists($table, $name) { + global $db_type; + if ($db_type == 'mysql' || $db_type == 'mysqli') { + if (version_compare(db_version(), '5.0.3') < 0) { + // Earlier versions of MySQL don't support a WHERE clause for SHOW. + $result = db_query('SHOW INDEX FROM {'. $table .'}'); + while ($row = db_fetch_array($result)) { + if ($row['Key_name'] == $name) { + return TRUE; + } + } + return FALSE; + } + return (bool)db_result(db_query("SHOW INDEX FROM {". $table ."} WHERE key_name = '$name'")); + } + elseif ($db_type == 'pgsql') { + // Note that the index names in Schema API for PostgreSQL are prefixed by + // the table name and suffixed by '_idx'. + return (bool)db_result(db_query("SELECT COUNT(indexname) FROM pg_indexes WHERE indexname = '{". $table ."}_{$name}_idx'")); + } + return FALSE; +} + +/** + * Helper function for determining the behavior of a field or a widget + * with respect to a given operation. (currently used for field 'view', + * and widget 'default values' and 'multiple values') + * + * @param $entity + * 'field' or 'widget' + * @param $op + * the name of the operation ('view', 'default value'...) + * @param $field + * The field array, including widget info. + * @return + * CONTENT_CALLBACK_NONE - do nothing for this operation + * CONTENT_CALLBACK_CUSTOM - use the module's callback function. + * CONTENT_CALLBACK_DEFAULT - use content module default behavior + * + */ +function content_callback($entity, $op, $field) { + switch ($entity) { + case 'field': + $info = module_invoke($field['module'], "field_info"); + return isset($info[$field['type']]['callbacks'][$op]) ? $info[$field['type']]['callbacks'][$op] : CONTENT_CALLBACK_DEFAULT; + + case 'widget': + $info = module_invoke($field['widget']['module'], "widget_info"); + return isset($info[$field['widget']['type']]['callbacks'][$op]) ? $info[$field['widget']['type']]['callbacks'][$op] : CONTENT_CALLBACK_DEFAULT; + } +} + +/** + * Helper function for determining the handling of a field, widget or + * formatter with respect to a given operation. + * + * Currently used for widgets and formatters 'multiple values'. + * + * @param $entity + * 'field', 'widget' or 'formatter' + * @param $op + * the name of the operation ('default values'...) + * @param $object + * - if $entity is 'field' or 'widget': the field array, + * including widget info. + * - if $entity is 'formater': the formatter array. + * @return + * CONTENT_HANDLE_CORE - the content module handles this operation. + * CONTENT_HANDLE_MODULE - the implementing module handles this operation. + */ +function content_handle($entity, $op, $object) { + switch ($entity) { + case 'field': + $info = module_invoke($object['module'], "field_info"); + return isset($info[$object['type']][$op]) ? $info[$object['type']][$op] : CONTENT_HANDLE_CORE; + + case 'widget': + $info = module_invoke($object['widget']['module'], "widget_info"); + return isset($info[$object['widget']['type']][$op]) ? $info[$object['widget']['type']][$op] : CONTENT_HANDLE_CORE; + + case 'formatter': + // Much simpler, formatters arrays *are* the 'formatter_info' itself. + // We let content_handle deal with them only for code consistency. + return isset($object[$op]) ? $object[$op] : CONTENT_HANDLE_CORE; + } +} + +/** + * Helper function to return the correct default value for a field. + * + * @param $node + * The node. + * @param $field + * The field array. + * @param $items + * The value of the field in the node. + * @return + * The default value for that field. + */ +function content_default_value(&$form, &$form_state, $field, $delta) { + $widget_types = _content_widget_types(); + $module = $widget_types[$field['widget']['type']]['module']; + + $default_value = array(); + if (!empty($field['widget']['default_value_php'])) { + ob_start(); + $result = eval($field['widget']['default_value_php']); + ob_end_clean(); + if (is_array($result)) { + $default_value = $result; + } + } + elseif (!empty($field['widget']['default_value'])) { + $default_value = $field['widget']['default_value']; + } + return (array) $default_value; +} + +/** + * Determine whether the user has access to a given field. + * + * @param $op + * The operation to be performed. Possible values: + * - "edit" + * - "view" + * @param $field + * The field on which the operation is to be performed. + * @param $account + * (optional) The account to check, if not given use currently logged in user. + * @param $node + * (optional) The node on which the operation is to be performed. + * @return + * TRUE if the operation is allowed; + * FALSE if the operation is denied. + */ +function content_access($op, $field, $account = NULL, $node = NULL) { + global $user; + + if (is_null($account)) { + $account = $user; + } + // Check for valid field data. + if (!isset($field['field_name'])) { + return FALSE; + } + $access = module_invoke_all('field_access', $op, $field, $account, $node); + foreach ($access as $value) { + if ($value === FALSE) { + return FALSE; + } + } + return TRUE; +} + + /** + * Hide specified fields from the $content variable in node templates. + */ +function content_field_wrapper_post_render($content, $element) { + $field = content_fields($element['#field_name'], $element['#type_name']); + if (theme('content_exclude', $content, $field, $element['#context'])) { + return ''; + } + return $content; +} + + +/** + * 'Theme' function for a field's addition to $content. + * + * Adapts the all-inclusive $content variable in node templates to allow + * some field content to be excluded. This is a theme function, so it can be + * overridden in different themes to produce different results. + * + * The html for individual fields and groups are available in the + * $FIELD_NAME_rendered and $GROUP_NAME_rendered variables. + * + * This allows more flexibility in node templates : you can use custom markup + * around a few specific fields, and print the rest of the node with $content. + * + * @param $content + * The themed content for this field or group. + * + * @param $object + * The field or group array for this item. + * $object['#type_name'] holds the content type. + * $object['#field_name'] holds the field name (if a field). + * $object['#group_name'] holds the group name (if a group). + * $object['display_settings'] holds the display settings + * for all contexts, in an array like: + * $object['display_settings'] => array( + * 'full' => array( + * 'format' => 'default', + * 'exclude' => 0, + * ), + * 'teaser' => array( + * 'format' => 'default', + * 'exclude' => 1, + * ), + * ); + * + * @param $context + * The context for which the node is being rendered. + * Can be one of the following values : + * - 'teaser' + * - 'full' + * - NODE_BUILD_SEARCH_INDEX + * - NODE_BUILD_SEARCH_RESULT + * - NODE_BUILD_RSS + * - NODE_BUILD_PRINT + * - ... any other custom build mode exposed by 3rd party modules using + * hook_content_build_modes(). + * + * @return + * Whether or not content is to be added to $content in this context. + * Uses the value of the 'Exclude' checkbox for this field + * as set on the Manage fields screen. + */ +function theme_content_exclude($content, $object, $context) { + // The field may be missing info for $contexts added by modules + // enabled after the field was last edited. + if (empty($object['display_settings']) + || empty($object['display_settings'][$context]) + || !is_array($object['display_settings'][$context]) + || empty($object['display_settings'][$context]['exclude'])) { + return FALSE; + } + else { + return TRUE; + } +} + +/** + * Theme preprocess function for field.tpl.php. + * + * The $variables array contains the following arguments: + * - $node + * - $field + * - $items + * - $teaser + * - $page + * + * @see field.tpl.php + * + * TODO : this should live in theme/theme.inc, but then the preprocessor + * doesn't get called when the theme overrides the template. Bug in theme layer ? + */ +function template_preprocess_content_field(&$variables) { + $element = $variables['element']; + $field = content_fields($element['#field_name'], $element['#node']->type); + + $variables['node'] = $element['#node']; + $variables['field'] = $field; + $variables['items'] = array(); + + if ($element['#single']) { + // Single value formatter. + foreach (element_children($element['items']) as $delta) { + $variables['items'][$delta] = $element['items'][$delta]['#item']; + // Use isset() to avoid undefined index message on #children when field values are empty. + $variables['items'][$delta]['view'] = isset($element['items'][$delta]['#children']) ? $element['items'][$delta]['#children'] : ''; + } + } + else { + // Multiple values formatter. + // We display the 'all items' output as $items[0], as if it was the + // output of a single valued field. + // Raw values are still exposed for all items. + foreach (element_children($element['items']) as $delta) { + $variables['items'][$delta] = $element['items'][$delta]['#item']; + } + $variables['items'][0]['view'] = $element['items']['#children']; + } + + $variables['teaser'] = $element['#teaser']; + $variables['page'] = $element['#page']; + + $field_empty = TRUE; + + foreach ($variables['items'] as $delta => $item) { + if (!isset($item['view']) || (empty($item['view']) && (string)$item['view'] !== '0')) { + $variables['items'][$delta]['empty'] = TRUE; + } + else { + $field_empty = FALSE; + $variables['items'][$delta]['empty'] = FALSE; + } + } + + $additions = array( + 'field_type' => $field['type'], + 'field_name' => $field['field_name'], + 'field_type_css' => strtr($field['type'], '_', '-'), + 'field_name_css' => strtr($field['field_name'], '_', '-'), + 'label' => check_plain(t($field['widget']['label'])), + 'label_display' => $element['#label_display'], + 'field_empty' => $field_empty, + 'template_files' => array( + 'content-field', + 'content-field-'. $element['#field_name'], + 'content-field-'. $element['#node']->type, + 'content-field-'. $element['#field_name'] .'-'. $element['#node']->type, + ), + ); + $variables = array_merge($variables, $additions); +} + +/** + * Theme preprocess function for node. + * + * - Adds $FIELD_NAME_rendered variables + * containing the themed output for the whole field. + * - Adds the formatted values in the 'view' key of the items. + */ +function content_preprocess_node(&$vars) { + $additions = _content_field_invoke_default('preprocess_node', $vars['node']); + $vars = array_merge($vars, $additions); +} + +/** + * Debugging using hook_content_fieldapi. + * + * @TODO remove later + * + * @param $op + * @param $field + */ +function content_content_fieldapi($op, $field) { + if (module_exists('devel')) { + //dsm($op); + //dsm($field); + } +} + +/** + * Implementation of hook_content_extra_fields. + * + * Informations for non-CCK 'node fields' defined in core. + */ +function content_content_extra_fields($type_name) { + $type = node_get_types('type', $type_name); + $extra = array(); + + if ($type->has_title) { + $extra['title'] = array( + 'label' => $type->title_label, + 'description' => t('Node module form.'), + 'weight' => -5 + ); + } + if ($type->has_body) { + $extra['body_field'] = array( + 'label' => $type->body_label, + 'description' => t('Node module form.'), + 'weight' => 0, + 'view' => 'body' + ); + } + $extra['revision_information'] = array( + 'label' => t('Revision information'), + 'description' => t('Node module form.'), + 'weight' => 20 + ); + $extra['author'] = array( + 'label' => t('Authoring information'), + 'description' => t('Node module form.'), + 'weight' => 20, + ); + $extra['options'] = array( + 'label' => t('Publishing options'), + 'description' => t('Node module form.'), + 'weight' => 25, + ); + if (module_exists('comment')) { + $extra['comment_settings'] = array( + 'label' => t('Comment settings'), + 'description' => t('Comment module form.'), + 'weight' => 30 + ); + } + if (module_exists('locale') && variable_get("language_content_type_$type_name", 0)) { + $extra['language'] = array( + 'label' => t('Language'), + 'description' => t('Locale module form.'), + 'weight' => 0 + ); + } + if (module_exists('translation') && translation_supported_type($type_name)) { + $extra['translation'] = array( + 'label' => t('Translation settings'), + 'description' => t('Translation module form.'), + 'weight' => 30 + ); + } + if (module_exists('menu')) { + $extra['menu'] = array( + 'label' => t('Menu settings'), + 'description' => t('Menu module form.'), + 'weight' => -2 + ); + } + if (module_exists('taxonomy') && taxonomy_get_vocabularies($type_name)) { + $extra['taxonomy'] = array( + 'label' => t('Taxonomy'), + 'description' => t('Taxonomy module form.'), + 'weight' => -3 + ); + } + if (module_exists('book')) { + $extra['book'] = array( + 'label' => t('Book'), + 'description' => t('Book module form.'), + 'weight' => 10 + ); + } + if (module_exists('path')) { + $extra['path'] = array( + 'label' => t('Path settings'), + 'description' => t('Path module form.'), + 'weight' => 30 + ); + } + if ($type_name == 'poll' && module_exists('poll')) { + $extra['title'] = array( + 'label' => t('Poll title'), + 'description' => t('Poll module title.'), + 'weight' => -5 + ); + $extra['choice_wrapper'] = array( + 'label' => t('Poll choices'), + 'description' => t('Poll module choices.'), + 'weight' => -4 + ); + $extra['settings'] = array( + 'label' => t('Poll settings'), + 'description' => t('Poll module settings.'), + 'weight' => -3 + ); + } + if (module_exists('upload') && variable_get("upload_$type_name", TRUE)) { + $extra['attachments'] = array( + 'label' => t('File attachments'), + 'description' => t('Upload module form.'), + 'weight' => 30, + 'view' => 'files' + ); + } + + return $extra; +} + +/** + * Retrieve the user-defined weight for non-CCK node 'fields'. + * + * CCK's 'Manage fields' page lets users reorder node fields, including non-CCK + * items (body, taxonomy, other hook_nodeapi-added elements by contrib modules...). + * Contrib modules that want to have their 'fields' supported need to expose + * them with hook_content_extra_fields, and use this function to retrieve the + * user-defined weight. + * + * @param $type_name + * The content type name. + * @param $pseudo_field_name + * The name of the 'field'. + * @return + * The weight for the 'field', respecting the user settings stored + * by content.module. + */ +function content_extra_field_weight($type_name, $pseudo_field_name) { + $type = content_types($type_name); + + // If we don't have the requested item, this may be because the cached + // information for 'extra' fields hasn't been refreshed yet. + if (!isset($type['extra'][$pseudo_field_name])) { + content_clear_type_cache(); + $type = content_types($type_name); + } + + if (isset($type['extra'][$pseudo_field_name])) { + return $type['extra'][$pseudo_field_name]['weight']; + } +} + +/** + * Find max delta value actually in use for a field. + * + * Helper function to do things like tell when we should prevent a + * change in multiple value settings that would result in data loss, + * or know if content actually exists for a field. + * + * @param $field_name + * The field name to examine. + * @param $type_name + * If provided, search only for existing data in that type, + * otherwise search for all instances of field data in all types. + * @return + * NULL if field is not in use, or the maximum delta value in use. + * + * TODO + * Go back to the field settings validation and use this function + * to prevent (or confirm) changes in multiple values that + * would destroy data. + * + * Fields with only NULL data will show up as being in use. + * Do we want to eliminate them from the results? + */ +function content_max_delta($field_name, $type_name = NULL) { + $fields = content_fields(); + $field = $fields[$field_name]; + + // Non-multiple value fields don't use the delta column, + // but could exist in multiple databases. If any value + // exists in any examined table, the max delta will be zero. + if (empty($field['multiple'])) { + $content_types = content_types(); + foreach ($content_types as $content_type) { + if (empty($type_name) || $content_type['type'] == $type_name) { + foreach ($content_type['fields'] as $field) { + $db_info = content_database_info($field); + if (db_result(db_query("SELECT COUNT(*) FROM {". $db_info['table'] ."}")) >= 1) { + return 0; + } + } + } + } + } + // Multiple value fields always share the same table and use the delta. + // If we want to find delta values for a particular type, we join + // in the node table to limit the type. + else { + $db_info = content_database_info($field); + if (!empty($type_name)) { + $delta = db_result(db_query("SELECT MAX(delta) FROM {". $db_info['table'] ."} f LEFT JOIN {node} n ON f.vid = n.vid WHERE n.type = '%s'", $type_name)); + } + else { + $delta = db_result(db_query("SELECT MAX(delta) FROM {". $db_info['table'] ."}")); + } + if ($delta >= 0) { + return $delta; + } + } + // If we got this far, there is no data for this field. + return NULL; +} + +/** + * Helper function to identify inactive fields. + */ +function content_inactive_fields($type_name = NULL) { + module_load_include('inc', 'content', 'includes/content.crud'); + if (!empty($type_name)) { + $param = array('type_name' => $type_name); + $inactive = array($type_name => array()); + } + else { + $param = array(); + $inactive = array(); + } + $all = content_field_instance_read($param, TRUE); + $active = array_keys(content_fields()); + foreach ($all as $field) { + if (!in_array($field['field_name'], $active)) { + $inactive[$field['type_name']][$field['field_name']] = content_field_instance_expand($field); + } + } + if (!empty($type_name)) { + return $inactive[$type_name]; + } + return $inactive; +} + + +/** + * Helper function to identify inactive instances. + * This will be the same results as content_inactive_fields(), + * EXCEPT that his function will return inactive instances even + * if the fields have other (shared) instances that are still active. + */ +function content_inactive_instances($type_name = NULL) { + module_load_include('inc', 'content', 'includes/content.crud'); + if (!empty($type_name)) { + $param = array('type_name' => $type_name); + $inactive = array($type_name => array()); + } + else { + $param = array(); + $inactive = array(); + } + $all = content_field_instance_read($param, TRUE); + foreach ($all as $field) { + $inactive[$field['type_name']][$field['field_name']] = content_field_instance_expand($field); + } + if (!empty($type_name)) { + return $inactive[$type_name]; + } + return $inactive; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.html b/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.html new file mode 100644 index 0000000000000000000000000000000000000000..024007cae58cca7a3ab163068886e0f3756b5b8d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.html @@ -0,0 +1,47 @@ +<!-- $Id$ --> +<p>Using a field across several content type can be handy if a piece of data +is relevant for several content types. A typical use case is a 'Phone number' +field, used in both 'Restaurant' and 'Hotel' content types, even if hotels +and restaurants are different enough to deserve their own specific set of +fields and thus their own dedicated content types.</p> + +<p>When a field has been added to more than one content type, we also say it is +"shared", and that it as "several instances".</p> + +<p>At the bottom of the <strong>Manage fields</strong> page for a content type, +you'll find this:</p> + +<img src="&path&add-existing-field.png"> + +<p>In order to add a new instance of an existing field to a content type, you +need to provide the following information:</p> +<dl> + <dt><strong>Label:</strong></dt> + <dd> + A human-readable name for the field. It will be used in input forms and + on displayed content.<br/> + All characters are allowed, including spaces, accentuated or non-european + characters.<br/> + </dd> + + <dt><strong>Field:</strong></dt> + <dd> + The field to be shared.<br/> + A field cannot appear more than once in each content type. Thus, only + fields that are not already present in the current content type will be + proposed as "shareable". If none, the <strong>Add existing field</strong> + option is not available on the <strong>Manage fields</strong> page for + this content type.<br/> + Selecting a field automatically populates the <strong>Label</strong> and + <strong>Widget</strong> values with the ones used by the previous field + instance, but you can change them if needed before submitting the form. + </dd> + + <dt><strong>Widget:</strong></dt> + <dd> + The form element that will be used to input data for this field on + content forms : text input, select list, etc...<br/> + Each field type has its own list of available widgets. When selecting a + field to share, the list of widgets you can select is automatically updated. + </dd> +</dl> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.png b/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.png new file mode 100644 index 0000000000000000000000000000000000000000..4b126650ccf0e78633fb4c6fd61f8a1532387e4a Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.html b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.html new file mode 100644 index 0000000000000000000000000000000000000000..7c9de37ee95b32ff3854266549868591d8ea9847 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.html @@ -0,0 +1,58 @@ +<!-- $Id$ --> +<p>At the bottom of the <strong>Manage fields</strong> page for a content type, +you'll find this:</p> + +<img src="&path&add-new-field.png"> + +<p>In order to add a new field to a content type, you need to provide the +following information:</p> +<dl> + <dt>Label:</dt> + <dd> + A human-readable name for the field. It will be used in input forms and + on displayed content.<br/> + All characters are allowed, including spaces, accentuated or non-european + characters. + </dd> + + <dt>Field name:</dt> + <dd> + A machine-readable name for the field. It is used internally to identify + the field and handle database storage. When doing custom theming, it is + this identifier that you'll use to refer to that field.<br/> + <strong>Important:</strong> The field name cannot be changed once the field has been + created.<br/> + Allowed characters: a-z (unaccentuated), 0-9 and the underscore (_).<br/> + The length of the field name cannot exceed 32 characters (including the + 'field_' prefix that gets added automatically - that is, 26 free characters)<br/> + </dd> + + <dt>Field type:</dt> + <dd> + The type of data to be stored in that field.<br/> + <strong>Important:</strong> The field type cannot be changed once the field has been + created.<br/> + The available field types depend on the modules you have enabled on your site. CCK comes with 6 + basic field types : + <ul> + <li>Text</li> + <li>Integer</li> + <li>Float</li> + <li>Decimal</li> + <li>Node reference</li> + <li>User reference</li> + </ul> + Additional modules can be downloaded to handle other field types such as + dates, files, images... Look at the + <a href="http://www.drupal.org/project/cck" target="_blank"> CCK project page</a> + and the <a href="http://drupal.org/project/Modules/category/88" target="_blank">complete list of CCK-related modules</a>. + </dd> + + <dt>Widget:</dt> + <dd> + The form element that will be used to input data for this field on + content forms : text input, select list, etc...<br/> + Each field type has its own list of available widgets. When selecting a + field type, the list of widgets you can select is automatically updated. + </dd> +</dl> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.png b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.png new file mode 100644 index 0000000000000000000000000000000000000000..a7290443adbf6047e8930eee03c87c073ac5572d Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.html b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.html new file mode 100644 index 0000000000000000000000000000000000000000..0e3a61bc72c0311284fd3d1fbcbeec8c9a2ba6d3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.html @@ -0,0 +1,40 @@ +<!-- $Id$ --> +<p>Field groups are used to visually gather several fields that are associated +by some sort of logic, for instance several text fields that hold the different +parts of an 'Address'. On input forms and displayed content, the corresponding +fields are enclosed inside an HTML fieldset.</p> + +<img style="vertical-align:top" src="&path&group-node-edit-form.png"> +<img style="vertical-align:top" src="&path&group-node-display.png"> + +<p>At the bottom of the <strong>Manage fields</strong> page for a content type, +you'll find this:</p> + +<img src="&path&add-new-group.png"> + +<p>In order to add a new group to a content type, you need to provide the +following information:</p> +<dl> + <dt><strong>Label:</strong></dt> + <dd> + A human-readable name for the group. It will be used in input forms and + on displayed content.<br/> + All characters are allowed, including spaces, accentuated or non-european + characters.<br/> + </dd> + + <dt>Group name:</dt> + <dd> + A machine-readable name for the group. It is used internally to identify + the group. When doing custom theming, it is this identifier that you'll use + to refer to that group.<br/> + <strong>Important:</strong> The group name cannot be changed once the group has been + created.<br/> + Allowed characters: a-z (unaccentuated), 0-9 and the underscore (_).<br/> + The length of the group name cannot exceed 32 characters (including the + 'group_' prefix that gets added automatically - that is, 26 free characters)<br/> + </dd> +</dl> + +<p>Once a group has been created, you can define what fields it will enclose by +<a href="topic:content/rearrange">rearranging fields and groups</a>.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.png b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.png new file mode 100644 index 0000000000000000000000000000000000000000..cedbe445a328c90ada82799a0ca51c781b2a4342 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new.png b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new.png new file mode 100644 index 0000000000000000000000000000000000000000..bda9a223f0bd7d75a952a717058c12c216b30494 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add.html b/drupal/sites/default/boinc/modules/contrib/cck/help/add.html new file mode 100644 index 0000000000000000000000000000000000000000..91ff3a62862cd20de821620cc6a94781b3c7d3e6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/add.html @@ -0,0 +1,16 @@ +<!-- $Id$ --> +<p>The form elements at the bottom of the <strong>Manage fields</strong> page +let you add fields and groups to your content types.</p> + +<img src="&path&add-new.png"> + +<p style="font-size:smaller">(The <strong>Add existing field</strong> row is +displayed only if there are fields available in other content types. +The <strong>Add new group</strong> rows is displayed only if Fieldgroup module +is enabled.)</p> +<p>Your fields and groups will be created after you click the <strong>Save</strong> +button at the bottom of the page. In subsequent pages you will be presented +with the settings form for each field you added.</p> + +<p>You will find more details on the required informations in the +following pages:</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/content.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/help/content.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..89120a983ceb89f77b6cad39203281f598f5f45c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/content.help.ini @@ -0,0 +1,60 @@ +; $Id$ + +[advanced help settings] +name = CCK +index name = "CCK (Content Construction Kit)" + +[fields] +title = Fields and Widgets +weight = -10 + +[manage-fields] +title = 'Manage fields' tab + +[add] +title = Add fields and groups +parent = manage-fields +weight = 1 + +[add-new-field] +title = Add a new field +parent = add +weight = 1 + +[add-existing-field] +title = Add an existing field : share a field across content types +parent = add +weight = 2 + +[add-new-group] +title = Add a new group +parent = add +weight = 3 + +[rearrange] +title = Rearrange fields and groups +parent = manage-fields +weight = 2 + +[remove] +title = Remove fields and groups +parent = manage-fields +weight = 3 + +[theme] +title = Theming CCK data in nodes + +[theme-node-templates] +title = Node templates +parent = theme +weight = 1 + +[theme-field-templates] +title = Field templates +parent = theme +weight = 2 + +[theme-formatters] +title = Formatter theme functions +parent = theme +weight = 3 diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/drag-groups.png b/drupal/sites/default/boinc/modules/contrib/cck/help/drag-groups.png new file mode 100644 index 0000000000000000000000000000000000000000..8d13dc8eba6d813633de530f2eb4faa9aa28eaae Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/drag-groups.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/drag-new.png b/drupal/sites/default/boinc/modules/contrib/cck/help/drag-new.png new file mode 100644 index 0000000000000000000000000000000000000000..05c2c6959e15ce79f510fd55337f77f21f07cfa1 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/drag-new.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/draggable.png b/drupal/sites/default/boinc/modules/contrib/cck/help/draggable.png new file mode 100644 index 0000000000000000000000000000000000000000..3ab0bb89e9a6e32abc84cc810e2bdb880074ce50 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/draggable.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/fields.html b/drupal/sites/default/boinc/modules/contrib/cck/help/fields.html new file mode 100644 index 0000000000000000000000000000000000000000..789fa5fa1f4e41fa076fcf88f029dec2d00c3054 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/fields.html @@ -0,0 +1 @@ +<p>The Content Construction Kit (CCK) is composed of numerous field and widget modules that can be used to add fields to any content type.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-display.png b/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-display.png new file mode 100644 index 0000000000000000000000000000000000000000..78ce35bf54cdfbdeb728e04317455d670b1c2e83 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-display.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-edit-form.png b/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-edit-form.png new file mode 100644 index 0000000000000000000000000000000000000000..831dd76cc0f4998425429e2ab0e1edf2c318303a Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-edit-form.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/manage-fields.html b/drupal/sites/default/boinc/modules/contrib/cck/help/manage-fields.html new file mode 100644 index 0000000000000000000000000000000000000000..73eba4c0a9549afbc8f0c75b5d6b75253a09498b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/manage-fields.html @@ -0,0 +1,4 @@ +<!-- $Id$ --> +<p>This page lets you manage the CCK fields in your content type : add fields and +groups, rearrange them, access their configuration pages, remove them from the +content type.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/rearrange.html b/drupal/sites/default/boinc/modules/contrib/cck/help/rearrange.html new file mode 100644 index 0000000000000000000000000000000000000000..fc9fe8bb9100cdaaf635bc89f002503879b04a95 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/rearrange.html @@ -0,0 +1,25 @@ +<!-- $Id$ --> +<p>To change the order of fields, grab a drag-and-drop handle +<img src="&path&draggable.png"> and drag the field to a new location in the list +(grab a handle by clicking and holding the mouse while hovering over a handle +icon). Remember that your changes will not be saved until you click the +<strong>Save</strong> button at the bottom of the page.</p> + +<p>The order you define will be used both on input forms (when creating or +editing a post), and on content display (teasers, content page, RSS items...)</p> +<p>You can also change the order of non-CCK 'fields' like <strong>Title</strong> +or <strong>File attachments</strong>. Depending on the 'field', this will +affect input forms and/or content display (some of those 'fields' are not +displayed in both contexts).</p> +<p>If your content type has groups (requires the Fieldgroup module), you can +move a field inside a group by dragging it below the row of the group, and +then slightly to the right before dropping it. Note that groups can also be +reordered, but can currently not be nested inside other groups.</p> + +<img src="&path&drag-groups.png"> + +<p>When adding a field or a group, you can drag them directly to the +intended spot in the list of fields and groups that are already present in your +content type, before clicking <strong>Save</strong>:</p> + +<img src="&path&drag-new.png"> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/remove.html b/drupal/sites/default/boinc/modules/contrib/cck/help/remove.html new file mode 100644 index 0000000000000000000000000000000000000000..d0c7b31cd765fe07f3e51ca2f7c059c6621e7f60 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/remove.html @@ -0,0 +1,17 @@ +<!-- $Id$ --> +<h3>Removing a field</h3> + +<p>When you remove a field from a content type, the data it holds are +<strong>permanently</strong> erased. You will be asked to confirm this action</p> + +<p>You will have to manually update your Views, pathauto settings, etc... if +needed.</p> + +<p>Note : if the field is shared across several content types, removing it from +one content type does <strong>not</strong> affect the data for the other content +types.</p> + +<h3>Removing a group</h3> + +<p>Removing a group from a content type does <strong>not</strong> remove the fields +it contains, and therefore erases no field data.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme-field-templates.html b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-field-templates.html new file mode 100644 index 0000000000000000000000000000000000000000..63be7a3518f1fb36faa3fcacdfedcb7ae8ac8b58 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-field-templates.html @@ -0,0 +1,76 @@ +<!-- $Id$ --> +<p>Field-level theming determines how the values of a given field are +displayed. The resulting output ends up in the <span class="code">$content</span> +and <span class="code">$<FIELD_NAME>_rendered</span> variables in the node +templates.</p> + +<h3>Template files</h3> + +<p>In order to customize field themeing:</p> + +<ul> + <li> + Copy the <span class="code">content-field.tpl.php</span> template file into + your theme's root folder (please keep the contents of the + <span class="code">cck/theme</span> folder untouched. For the same reason, + need to copy the file instead of just moving it). + </li> + <li> + Edit that copy to your liking. See the comments in + <span class="code">cck/theme/content/content-field.tpl.php</span> for a list + of all variables available in this template. + </li> +</ul> + +<h3>Template suggestions</h3> + +<p>In addition, the theme layer will also look for field-specific variants +(suggestions), in the following order of precedence:</p> + +<dl> + <dt>content-field-<FIELD_NAME>-<CONTENT_TYPE_NAME>.tpl.php</dt> + <dd> + ex: <span class="code">content-field-field_myfield-story.tpl.php</span> - + If present, will be used to theme the 'field_myfield' field when displaying + a 'story' node. + </dd> + + <dt>content-field-<CONTENT_TYPE_NAME>.tpl.php</dt> + <dd> + ex: <span class="code">content-field-story.tpl.php</span> - If present, + will be used to theme all fields of 'story' nodes. + </dd> + + <dt>content-field-<FIELD_NAME>.tpl.php</dt> + <dd> + ex: <span class="code">content-field-field_myfield.tpl.php</span> - + If present, will be used to theme all 'field_myfield' field in all the + content types it appears in. + </dd> + + <dt>content-field.tpl.php</dt> + <dd> + If none of the above is present, the base template will be used. + </dd> +</dl> + +<strong>Important:</strong> +<ul> + <li> + Suggestions work only if the theme also has the base template file. + If your theme has <span class="code">content-field-*.tpl.php</span> files, + it must also have a <span class="code">content-field.tpl.php</span> file. + </li> + <li> + Whenever you add new template files in your theme, you need to + rebuild the theme registry, or the theme engine won't see them.<br/> + You can do that by :<br/> + - visiting the <a href="&base_url&admin/build/modules">Administer modules</a> page<br/> + - or using <a href="http://www.drupal.org/project/devel">Devel module</a>'s + 'clear cache' link. + </li> +</ul> + +<p>See the <a href="http://drupal.org/node/223440">Working with template suggestions</a> +section of the <a href="http://drupal.org/theme-guide">Theme guide for Drupal 6</a> +for more informations about templates and template suggestions.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme-formatters.html b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-formatters.html new file mode 100644 index 0000000000000000000000000000000000000000..efbe6e0a446abb95345dd420df0512284fa0f2cf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-formatters.html @@ -0,0 +1,14 @@ +<!-- $Id$ --> +<p>Formatters are used to turn the raw data for a single field value into html. +The <strong>Display Fields</strong> tab lets you chose which formatter you want to use +for each of your fields.</p> + +<p>In CCK 2.0 for Drupal 6, all formatters now go through the theme layer. +Therefore, overriding a formatter's theme is another way you can alter how your +values are displayed (whereas changing <span class="code">content-field.tpl.php</span> +lets you change the html that "wraps" the values).</p> + +<p>Most formatters come as theme functions, but some might use templates instead. +Either way, you can override them using the usual Drupal 6 theme override +practices. For more informations, see the <a href="http://drupal.org/theme-guide">Theme guide for Drupal 6</a>, +and more specifically the <a href="http://drupal.org/node/173880">Overriding themable output</a> section.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme-node-templates.html b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-node-templates.html new file mode 100644 index 0000000000000000000000000000000000000000..8118da0a34f61100ec5f8f0f892b3d8551c00cd0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-node-templates.html @@ -0,0 +1,131 @@ +<!-- $Id$ --> +<h3>Template files</h3> + +<p>All themes usually come with a default <span class="code">node.tpl.php</span> +template. Drupal core lets you use the following variant (suggestion):</p> + +<dl> + <dt>node-<CONTENT_TYPE_NAME>.tpl.php</dt> + <dd> + ex: <span class="code">node-story.tpl.php</span> - If present, will be used + to theme a 'story' node. + </dd> +</dl> + +<p><strong>Important:</strong> whenever you add new template files in your theme, you +need to rebuild the theme registry, or the theme engine won't see them.<br/> +You can do that by :<br/> +- visiting the <a href="&base_url&admin/build/modules">Administer modules</a> page<br/> +- or using <a href="http://www.drupal.org/project/devel">Devel module</a>'s +'clear cache' link.</p> + +<h3>Template variables</h3> + +<p>CCK makes the following variables available in your theme's node templates:</p> + +<dl> + <dt>$<FIELD_NAME>_rendered</dt> + <dd> + Contains the rendered html for the field, including the label and all the + field's values, with the settings defined on the <strong>Display fields</strong> tab. + </dd> + + <dt>$<GROUP_NAME>_rendered</dt> + <dd> + Contains the rendered html for the fieldgroup (if any), including the label + and all the group's fields, with the settings defined on the <strong>Display + fields</strong> tab.<br/> + This variable therefore includes the html contained in all the + <span class="code">$<FIELD_NAME>_rendered</span> variables for the + group's fields. + </dd> + + <dt>$FIELD_NAME</dt> + <dd> + Contains the raw values of the fields, in the usual array-format used + internally by CCK. What you find in there depends on the field type.<br/> + Each value also contains a <span class="code">'view'</span> element, that + holds the ready-to-display value as rendered by the formatter. For instance: + <pre> +array( + 0 => array( + 'nid' => 5, + 'view' => '<a href="node/5">Title of node 5</a>', + ), +);</pre> + <strong>Raw data are not sanitized for output, it is therefore not + advised to use them directly</strong>. Use the <span class="code">'view'</span> + value, or run the values through <span class="code">content_format()</span>. + </dd> +</dl> + +<h3>Excluding fields from the $content variable</h3> + +<p>By default, the <span class="code">$content</span> variable used in node +templates contains the rendered html for the whole node : CCK fields and +fieldgroups, but also body, file attachments, fivestar widgets, ...</p> + +<p>If for some fields you want to use the more fine-grained variables described +above, you might want to use the <strong>Exclude</strong> checkboxes on the <strong>Display +fields</strong> screen, so that the output of those fields is excluded from the +<span class="code">$content</span> variable.</p> + +<p>You can then customize the display and layout of some CCK fields or groups +using the <span class="code">$<FIELD_NAME>_rendered</span> / +<span class="code">$<GROUP_NAME>_rendered</span> variables, and trust +<span class="code">$content</span> to display 'the rest' without getting +duplicate information.</p> + +<h5>Advanced trick</h5> +<p>The <strong>Exclude</strong> checkboxes affect all active themes. On sites with multiple +themes, however, the list of fields to exclude from <span class="code">$content</span> +might need to be different across the themes, depending on how their respective +node templates are structured.</p> + +<p>A theme can bypass those settings by overriding the <span class="code">theme_content_exclude()</span> +function to specify the list of fields to exclude for this theme (see the +PHPDoc of the function for more information).</p> + + +<h3>Special case : nodes in nodereference fields</h3> + +<p>In addition to the above, the following suggestions will be looked for +in priority for nodes that are displayed as values of a nodereference field using +the 'teaser' or 'full node' formatters:</p> + +<dl> + <dt>node-nodereference-<REFERRING_FIELD_NAME>-<TYPE_NAME>.tpl.php</dt> + <dd> + ex: <span class="code">node-nodereference-field_noderef-story.tpl.php</span> - + If present, will be used to theme a 'story' node when refererenced in the + 'field_noderef' field. + </dd> + + <dt>node-nodereference-<TYPE_NAME>.tpl.php</dt> + <dd> + ex: <span class="code">node-nodereference-story.tpl.php</span> - If present, + will be used to theme a 'story' node when refererenced in any nodereference + field. + </dd> + + <dt>node-nodereference-<REFERRING_FIELD_NAME>.tpl.php</dt> + <dd> + ex: <span class="code">node-nodereference-field_noderef.tpl.php</span> - If + present, will be used to a node refererenced in the 'field_noderef' field. + </dd> + + <dt>node-nodereference.tpl.php</dt> + <dd> + If present, will be used to theme nodes referenced in nodereference fields. + </dd> +</dl> + +<p>The following additional variables are available in templates for referenced nodes:</p> + +<dl> + <dt>$referring_field</dt> + <dd>The nodereference field that references the current node.</dd> + + <dt>$referring_node</dt> + <dd>The node referencing the current node.</dd> +</dl> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme.html b/drupal/sites/default/boinc/modules/contrib/cck/help/theme.html new file mode 100644 index 0000000000000000000000000000000000000000..e2f60fa45ed3416601d2bb0fc22813363d22b9a3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/help/theme.html @@ -0,0 +1,10 @@ +<!-- $Id$ --> +<p><strong>Note:</strong> these instructions assume you are familiar with the basic concepts +of Drupal 6 theming. For more informations, see the <a href="http://drupal.org/theme-guide">Theme guide for Drupal 6</a>, +and more specifically the <a href="http://drupal.org/node/173880">Overriding themable output</a> +section.</p> + +<p>There are 3 levels where you can customize how the data in CCK fields +is displayed in nodes:</p> + +<img src="&path&theme.png" class="content-border"> diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme.png b/drupal/sites/default/boinc/modules/contrib/cck/help/theme.png new file mode 100644 index 0000000000000000000000000000000000000000..d9281002edd7c88bce33858232a88b9147b53700 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/theme.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.admin.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..e0050f5b42110d2f6e0859bea95b313f5e886d73 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.admin.inc @@ -0,0 +1,1916 @@ +<?php +// $Id$ + +/** + * @file + * Administrative interface for content type creation. + */ + + +/** + * Menu callback; replacement for node_overview_types(). + */ +function content_types_overview() { + $types = node_get_types(); + $names = node_get_types('names'); + $header = array(t('Name'), t('Type'), t('Description'), array('data' => t('Operations'), 'colspan' => '4'),); + $rows = array(); + + foreach ($names as $key => $name) { + $type = $types[$key]; + if (node_hook($type, 'form')) { + $type_url_str = str_replace('_', '-', $type->type); + $row = array( + check_plain($name), + check_plain($type->type), + ); + // Make the description smaller + $row[] = array('data' => filter_xss_admin($type->description), 'class' => 'description'); + // Set the edit column. + $row[] = array('data' => l(t('edit'), 'admin/content/node-type/'. $type_url_str)); + // Set links for managing fields. + // TODO: a hook to allow other content modules to add more stuff? + $row[] = array('data' => l(t('manage fields'), 'admin/content/node-type/'. $type_url_str .'/fields')); + // Set the delete column. + if ($type->custom) { + $row[] = array('data' => l(t('delete'), 'admin/content/node-type/'. $type_url_str .'/delete')); + } + else { + $row[] = array('data' => ''); + } + + $rows[] = $row; + } + } + + // Allow external modules alter the table headers and rows. + foreach (module_implements('content_types_overview_alter') as $module) { + $function = $module .'_content_types_overview_alter'; + $function($header, $rows); + } + + if (empty($rows)) { + $rows[] = array(array('data' => t('No content types available.'), 'colspan' => '7', 'class' => 'message')); + } + + return theme('table', $header, $rows) .theme('content_overview_links'); +} + +function theme_content_overview_links() { + return '<div class="content-overview-links">'. l(t('» Add a new content type'), 'admin/content/types/add') .'</div>'; +} + +/** + * Menu callback; lists all defined fields for quick reference. + */ +function content_fields_list() { + $fields = content_fields(); + $field_types = _content_field_types(); + + // Sort fields by field name. + ksort($fields); + + $header = array(t('Field name'), t('Field type'), t('Used in')); + $rows = array(); + foreach ($fields as $field) { + $row = array(); + $row[] = $field['locked'] ? t('@field_name (Locked)', array('@field_name' => $field['field_name'])) : $field['field_name']; + $row[] = t($field_types[$field['type']]['label']); + + $types = array(); + $result = db_query("SELECT nt.name, nt.type FROM {". content_instance_tablename() ."} nfi ". + "LEFT JOIN {node_type} nt ON nt.type = nfi.type_name ". + "WHERE nfi.field_name = '%s' ". + // Keep disabled modules out of table. + "AND nfi.widget_active = 1 ". + "ORDER BY nt.name ASC", $field['field_name']); + while ($type = db_fetch_array($result)) { + $content_type = content_types($type['type']); + $types[] = l($type['name'], 'admin/content/node-type/'. $content_type['url_str'] .'/fields'); + } + $row[] = implode(', ', $types); + + $rows[] = array('data' => $row, 'class' => $field['locked'] ? 'menu-disabled' : ''); + } + if (empty($rows)) { + $output = t('No fields have been defined for any content type yet.'); + } + else { + $output = theme('table', $header, $rows); + } + return $output; +} + +/** + * Helper function to display a message about inactive fields. + */ +function content_inactive_message($type_name) { + $inactive_fields = content_inactive_fields($type_name); + if (!empty($inactive_fields)) { + $field_types = _content_field_types(); + $widget_types = _content_widget_types($type_name); + drupal_set_message(t('This content type has inactive fields. Inactive fields are not included in lists of available fields until their modules are enabled.'), 'error'); + foreach ($inactive_fields as $field_name => $field) { + drupal_set_message(t('!field (!field_name) is an inactive !field_type field that uses a !widget_type widget.', array( + '!field' => $field['widget']['label'], + '!field_name' => $field['field_name'], + '!field_type' => array_key_exists($field['type'], $field_types) ? $field_types[$field['type']]['label'] : $field['type'], + '!widget_type' => array_key_exists($field['widget']['type'], $widget_types) ? $widget_types[$field['widget']['type']]['label'] : $field['widget']['type'], + ))); + } + } +} + +/** + * Menu callback; listing of fields for a content type. + * + * Allows fields to be reordered and nested in fieldgroups using + * JS drag-n-drop. Non-CCK form elements can also be moved around. + */ +function content_field_overview_form(&$form_state, $type_name) { + + content_inactive_message($type_name); + + // When displaying the form, make sure the list of fields + // is up-to-date. + if (empty($form_state['post'])) { + content_clear_type_cache(); + } + + // Gather type information. + $type = content_types($type_name); + $fields = $type['fields']; + $field_types = _content_field_types(); + + $extra = $type['extra']; + $groups = $group_options = $group_types = array(); + if (module_exists('fieldgroup')) { + $groups = fieldgroup_groups($type['type']); + $group_types = fieldgroup_types(); + $group_options = _fieldgroup_groups_label($type['type']); + // Add the ability to group under the newly created row. + $group_options['_add_new_group'] = '_add_new_group'; + } + + // Store the default weights as we meet them, to be able to put the + //'add new' rows after them. + $weights = array(); + + $form = array( + '#tree' => TRUE, + '#type_name' => $type['type'], + '#fields' => array_keys($fields), + '#groups' => array_keys($groups), + '#extra' => array_keys($extra), + '#field_rows' => array(), + '#group_rows' => array(), + ); + + // Fields. + foreach ($fields as $name => $field) { + $weight = $field['widget']['weight']; + $form[$name] = array( + 'label' => array('#value' => check_plain($field['widget']['label'])), + 'field_name' => array('#value' => $field['field_name']), + 'type' => array('#value' => t($field_types[$field['type']]['label'])), + 'configure' => array('#value' => l(t('Configure'), 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $field['field_name'])), + 'remove' => array('#value' => l(t('Remove'), 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $field['field_name'] .'/remove')), + 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3), + 'parent' => array('#type' => 'select', '#options' => $group_options, '#default_value' => ''), + 'prev_parent' => array('#type' => 'hidden', '#value' => ''), + 'hidden_name' => array('#type' => 'hidden', '#default_value' => $field['field_name']), + '#leaf' => TRUE, + '#row_type' => 'field', + 'field' => array('#type' => 'value', '#value' => $field), + ); + if ($field['locked']) { + $form[$name]['configure'] = array('#value' => t('Locked')); + $form[$name]['remove'] = array(); + $form[$name]['#disabled_row'] = TRUE; + } + $form['#field_rows'][] = $name; + $weights[] = $weight; + } + + // Groups. + foreach ($groups as $name => $group) { + $weight = $group['weight']; + $form[$name] = array( + 'label' => array('#value' => check_plain($group['label'])), + 'group_name' => array('#value' => $group['group_name']), + 'group_type' => array('#value' => t($group_types[$group['group_type']])), + 'configure' => array('#value' => l(t('Configure'), 'admin/content/node-type/'. $type['url_str'] .'/groups/'. $group['group_name'])), + 'remove' => array('#value' => l(t('Remove'), 'admin/content/node-type/'. $type['url_str'] .'/groups/'. $group['group_name'] .'/remove')), + 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3), + 'parent' => array('#type' => 'hidden', '#default_value' => ''), + 'hidden_name' => array('#type' => 'hidden', '#default_value' => $group['group_name']), + '#root' => TRUE, + '#row_type' => 'group', + 'group' => array('#type' => 'value', '#value' => $group), + ); + // Adjust child fields rows. + foreach ($group['fields'] as $field_name => $field) { + $form[$field_name]['parent']['#default_value'] = $name; + $form[$field_name]['prev_parent']['#value'] = $name; + } + $form['#group_rows'][] = $name; + $weights[] = $weight; + } + + // Non-CCK 'fields'. + foreach ($extra as $name => $label) { + $weight = $extra[$name]['weight']; + $form[$name] = array( + 'label' => array('#value' => check_plain(t($extra[$name]['label']))), + 'description' => array('#value' => isset($extra[$name]['description']) ? $extra[$name]['description'] : ''), + 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3), + 'parent' => array('#type' => 'hidden', '#default_value' => ''), + 'configure' => array('#value' => isset($extra[$name]['configure']) ? $extra[$name]['configure'] : ''), + 'remove' => array('#value' => isset($extra[$name]['remove']) ? $extra[$name]['remove'] : ''), + 'hidden_name' => array('#type' => 'hidden', '#default_value' => $name), + '#leaf' => TRUE, + '#root' => TRUE, + '#disabled_row' => TRUE, + '#row_type' => 'extra', + ); + $form['#field_rows'][] = $name; + $weights[] = $weight; + } + + // Additional row : add new field. + $weight = max($weights) + 1; + $field_type_options = content_field_type_options(); + $widget_type_options = content_widget_type_options(NULL, TRUE); + if ($field_type_options && $widget_type_options) { + array_unshift($field_type_options, t('- Select a field type -')); + array_unshift($widget_type_options, t('- Select a widget -')); + $name = '_add_new_field'; + $form[$name] = array( + 'label' => array( + '#type' => 'textfield', + '#size' => 15, + '#description' => t('Label'), + ), + 'field_name' => array( + '#type' => 'textfield', + // This field should stay LTR even for RTL languages. + '#field_prefix' => '<span dir="ltr">field_', + '#field_suffix' => '</span>‎', + '#attributes' => array('dir'=>'ltr'), + '#size' => 15, + // Field names are limited to 32 characters including the 'field_' + // prefix which is 6 characters long. + '#maxlength' => 26, + '#description' => t('Field name (a-z, 0-9, _)'), + ), + 'type' => array( + '#type' => 'select', + '#options' => $field_type_options, + '#description' => theme('advanced_help_topic', 'content', 'fields') . t('Type of data to store.'), + ), + 'widget_type' => array( + '#type' => 'select', + '#options' => $widget_type_options, + '#description' => t('Form element to edit the data.'), + ), + 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3), + 'parent' => array('#type' => 'select', '#options' => $group_options, '#default_value' => ''), + 'hidden_name' => array('#type' => 'hidden', '#default_value' => $name), + '#leaf' => TRUE, + '#add_new' => TRUE, + '#row_type' => 'add_new_field', + ); + $form['#field_rows'][] = $name; + } + + // Additional row : add existing field. + $existing_field_options = content_existing_field_options($type_name); + if ($existing_field_options && $widget_type_options) { + $weight++; + array_unshift($existing_field_options, t('- Select an existing field -')); + $name = '_add_existing_field'; + $form[$name] = array( + 'label' => array( + '#type' => 'textfield', + '#size' => 15, + '#description' => t('Label'), + ), + 'field_name' => array( + '#type' => 'select', + '#options' => $existing_field_options, + '#description' => t('Field to share'), + ), + 'widget_type' => array( + '#type' => 'select', + '#options' => $widget_type_options, + '#description' => t('Form element to edit the data.'), + ), + 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3), + 'parent' => array('#type' => 'select', '#options' => $group_options, '#default_value' => ''), + 'hidden_name' => array('#type' => 'hidden', '#default_value' => $name), + '#leaf' => TRUE, + '#add_new' => TRUE, + '#row_type' => 'add_existing_field', + ); + $form['#field_rows'][] = $name; + } + + // Additional row : add new group. + if (!empty($group_types)) { + $weight++; + $name = '_add_new_group'; + $form[$name] = array( + 'label' => array( + '#type' => 'textfield', + '#size' => 15, + '#description' => t('Label'), + ), + 'group_name' => array( + '#type' => 'textfield', + // This field should stay LTR even for RTL languages. + '#field_prefix' => '<span dir="ltr">group_', + '#field_suffix' => '</span>‎', + '#attributes' => array('dir'=>'ltr'), + '#size' => 15, + // Group names are limited to 32 characters including the 'group_' + // prefix which is 6 characters long. + '#maxlength' => 26, + '#description' => t('Group name (a-z, 0-9, _)'), + ), + 'group_option' => array( + '#type' => 'hidden', + '#value' => '', + ), + 'group_type' => array( + '#type' => 'hidden', + '#value' => 'standard', + ), + 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3), + 'parent' => array('#type' => 'hidden', '#default_value' => ''), + 'hidden_name' => array('#type' => 'hidden', '#default_value' => $name), + '#root' => TRUE, + '#add_new' => TRUE, + '#row_type' => 'add_new_group', + ); + if (count($group_types) > 1) { + $form[$name]['group_type'] = array( + '#type' => 'select', + '#description' => t('Type of group.'), + '#options' => $group_types, + '#default_value' => 'standard', + ); + } + $form['#group_rows'][] = $name; + } + + $form['submit'] = array('#type' => 'submit', '#value' => t('Save')); + return $form; +} + +function content_field_overview_form_validate($form, &$form_state) { + _content_field_overview_form_validate_add_new($form, $form_state); + _content_field_overview_form_validate_add_existing($form, $form_state); +} + +/** + * Helper function for content_field_overview_form_validate. + * + * Validate the 'add new field' row. + */ +function _content_field_overview_form_validate_add_new($form, &$form_state) { + $field = $form_state['values']['_add_new_field']; + + // Validate if any information was provided in the 'add new field' row. + if (array_filter(array($field['label'], $field['field_name'], $field['type'], $field['widget_type']))) { + // No label. + if (!$field['label']) { + form_set_error('_add_new_field][label', t('Add new field: you need to provide a label.')); + } + + // No field name. + if (!$field['field_name']) { + form_set_error('_add_new_field][field_name', t('Add new field: you need to provide a field name.')); + } + // Field name validation. + else { + $field_name = $field['field_name']; + + // Add the 'field_' prefix. + if (substr($field_name, 0, 6) != 'field_') { + $field_name = 'field_'. $field_name; + form_set_value($form['_add_new_field']['field_name'], $field_name, $form_state); + } + + // Invalid field name. + if (!preg_match('!^field_[a-z0-9_]+$!', $field_name)) { + form_set_error('_add_new_field][field_name', t('Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores.', array('%field_name' => $field_name))); + } + if (strlen($field_name) > 32) { + form_set_error('_add_new_field][field_name', t('Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the \'field_\' prefix.', array('%field_name' => $field_name))); + } + // A field named 'field_instance' would cause a tablename clash with {content_field_instance} + if ($field_name == 'field_instance') { + form_set_error('_add_new_field][field_name', t("Add new field: the name 'field_instance' is a reserved name.")); + } + + // Field name already exists. + // We need to check inactive fields as well, so we can't use content_fields(). + module_load_include('inc', 'content', 'includes/content.crud'); + $fields = content_field_instance_read(array(), TRUE); + $used = FALSE; + foreach ($fields as $existing_field) { + $used |= ($existing_field['field_name'] == $field_name); + } + if ($used) { + form_set_error('_add_new_field][field_name', t('Add new field: the field name %field_name already exists.', array('%field_name' => $field_name))); + } + } + + // No field type. + if (!$field['type']) { + form_set_error('_add_new_field][type', t('Add new field: you need to select a field type.')); + } + + // No widget type. + if (!$field['widget_type']) { + form_set_error('_add_new_field][widget_type', t('Add new field: you need to select a widget.')); + } + // Wrong widget type. + elseif ($field['type']) { + $widget_types = content_widget_type_options($field['type']); + if (!isset($widget_types[$field['widget_type']])) { + form_set_error('_add_new_field][widget_type', t('Add new field: invalid widget.')); + } + } + } +} + +/** + * Helper function for content_field_overview_form_validate. + * + * Validate the 'add existing field' row. + */ +function _content_field_overview_form_validate_add_existing($form, &$form_state) { + // The form element might be absent if no existing fields can be added to + // this content type + if (isset($form_state['values']['_add_existing_field'])) { + $field = $form_state['values']['_add_existing_field']; + + // Validate if any information was provided in the 'add existing field' row. + if (array_filter(array($field['label'], $field['field_name'], $field['widget_type']))) { + // No label. + if (!$field['label']) { + form_set_error('_add_existing_field][label', t('Add existing field: you need to provide a label.')); + } + + // No existing field. + if (!$field['field_name']) { + form_set_error('_add_existing_field][field_name', t('Add existing field: you need to select a field.')); + } + + // No widget type. + if (!$field['widget_type']) { + form_set_error('_add_existing_field][widget_type', t('Add existing field: you need to select a widget.')); + } + // Wrong widget type. + elseif ($field['field_name'] && ($existing_field = content_fields($field['field_name']))) { + $widget_types = content_widget_type_options($existing_field['type']); + if (!isset($widget_types[$field['widget_type']])) { + form_set_error('_add_existing_field][widget_type', t('Add existing field: invalid widget.')); + } + } + } + } +} + +function content_field_overview_form_submit($form, &$form_state) { + $form_values = $form_state['values']; + + $type_name = $form['#type_name']; + $type = content_types($type_name); + + // Update field weights. + $extra = array(); + foreach ($form_values as $key => $values) { + // Groups are handled in fieldgroup_content_overview_form_submit(). + if (in_array($key, $form['#fields'])) { + db_query("UPDATE {". content_instance_tablename() ."} SET weight = %d WHERE type_name = '%s' AND field_name = '%s'", + $values['weight'], $type_name, $key); + } + elseif (in_array($key, $form['#extra'])) { + $extra[$key] = $values['weight']; + } + } + + if ($extra) { + variable_set('content_extra_weights_'. $type_name, $extra); + } + else { + variable_del('content_extra_weights_'. $type_name); + } + + content_clear_type_cache(); + + $destinations = array(); + + // Create new field. + if (!empty($form_values['_add_new_field']['field_name'])) { + $field = $form_values['_add_new_field']; + $field['type_name'] = $type_name; + + module_load_include('inc', 'content', 'includes/content.crud'); + if (content_field_instance_create($field)) { + // Store new field information for fieldgroup submit handler. + $form_state['fields_added']['_add_new_field'] = $field['field_name']; + $destinations[] = 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $field['field_name']; + } + else { + drupal_set_message(t('There was a problem creating field %label.', array( + '%label' => $field['label']))); + } + } + + // Add existing field. + if (!empty($form_values['_add_existing_field']['field_name'])) { + $field = $form_values['_add_existing_field']; + $field['type_name'] = $type_name; + $existing_field = content_fields($field['field_name']); + + if ($existing_field['locked']) { + drupal_set_message(t('The field %label cannot be added to a content type because it is locked.', array('%label' => $field['field_name']))); + } + else { + module_load_include('inc', 'content', 'includes/content.crud'); + if (content_field_instance_create($field)) { + // Store new field information for fieldgroup submit handler. + $form_state['fields_added']['_add_existing_field'] = $field['field_name']; + $destinations[] = 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $field['field_name']; + } + else { + drupal_set_message(t('There was a problem adding field %label.', array('%label' => $field['field_name']))); + } + } + } + + if ($destinations) { + $destinations[] = urldecode(substr(drupal_get_destination(), 12)); + unset($_REQUEST['destination']); + $form_state['redirect'] = content_get_destinations($destinations); + } + +} + +/** + * Menu callback; presents a listing of fields display settings for a content type. + * + * Form includes form widgets to select which fields appear for teaser, full node + * and how the field labels should be rendered. + */ +function content_display_overview_form(&$form_state, $type_name, $contexts_selector = 'basic') { + content_inactive_message($type_name); + + // Gather type information. + $type = content_types($type_name); + $field_types = _content_field_types(); + $fields = $type['fields']; + + $groups = array(); + if (module_exists('fieldgroup')) { + $groups = fieldgroup_groups($type['type']); + } + $contexts = content_build_modes($contexts_selector); + + $form = array( + '#tree' => TRUE, + '#type_name' => $type['type'], + '#fields' => array_keys($fields), + '#groups' => array_keys($groups), + '#contexts' => $contexts_selector, + ); + + if (empty($fields)) { + drupal_set_message(t('There are no fields configured for this content type. You can add new fields on the <a href="@link">Manage fields</a> page.', array( + '@link' => url('admin/content/node-type/'. $type['url_str'] .'/fields'))), 'warning'); + return $form; + } + + // Fields. + $label_options = array( + 'above' => t('Above'), + 'inline' => t('Inline'), + 'hidden' => t('<Hidden>'), + ); + foreach ($fields as $name => $field) { + $field_type = $field_types[$field['type']]; + $defaults = $field['display_settings']; + $weight = $field['widget']['weight']; + + $form[$name] = array( + 'human_name' => array('#value' => check_plain($field['widget']['label'])), + 'weight' => array('#type' => 'value', '#value' => $weight), + 'parent' => array('#type' => 'value', '#value' => ''), + ); + + // Label + if ($contexts_selector == 'basic') { + $form[$name]['label']['format'] = array( + '#type' => 'select', + '#options' => $label_options, + '#default_value' => isset($defaults['label']['format']) ? $defaults['label']['format'] : 'above', + ); + } + + // Formatters. + $options = array(); + foreach ($field_type['formatters'] as $formatter_name => $formatter_info) { + $options[$formatter_name] = $formatter_info['label']; + } + $options['hidden'] = t('<Hidden>'); + + foreach ($contexts as $key => $value) { + $form[$name][$key]['format'] = array( + '#type' => 'select', + '#options' => $options, + '#default_value' => isset($defaults[$key]['format']) ? $defaults[$key]['format'] : 'default', + ); + // exclude from $content + $form[$name][$key]['exclude'] = array( + '#type' => 'checkbox', + '#options' => array(0 => t('Include'), 1 => t('Exclude')), + '#default_value' => isset($defaults[$key]['exclude']) ? $defaults[$key]['exclude'] : 0, + ); + } + } + + // Groups. + $label_options = array( + 'above' => t('Above'), + 'hidden' => t('<Hidden>'), + ); + $options = array( + 'no_style' => t('no styling'), + 'simple' => t('simple'), + 'fieldset' => t('fieldset'), + 'fieldset_collapsible' => t('fieldset - collapsible'), + 'fieldset_collapsed' => t('fieldset - collapsed'), + 'hidden' => t('<Hidden>'), + ); + foreach ($groups as $name => $group) { + $defaults = $group['settings']['display']; + $weight = $group['weight']; + + $form[$name] = array( + 'human_name' => array('#value' => check_plain($group['label'])), + 'weight' => array('#type' => 'value', '#value' => $weight), + ); + if ($contexts_selector == 'basic') { + $form[$name]['label'] = array( + '#type' => 'select', + '#options' => $label_options, + '#default_value' => isset($defaults['label']) ? $defaults['label'] : 'above', + ); + } + foreach ($contexts as $key => $title) { + $form[$name][$key]['format'] = array( + '#type' => 'select', + '#options' => $options, + '#default_value' => isset($defaults[$key]['format']) ? $defaults[$key]['format'] : 'fieldset', + ); + // exclude in $content + $form[$name][$key]['exclude'] = array( + '#type' => 'checkbox', + '#options' => array(0 => t('Include'), 1 => t('Exclude')), + '#default_value' => isset($defaults[$key]['exclude']) ? $defaults[$key]['exclude'] : 0, + ); + } + foreach ($group['fields'] as $field_name => $field) { + $form[$field_name]['parent']['#value'] = $name; + } + } + + $form['submit'] = array('#type' => 'submit', '#value' => t('Save')); + return $form; +} + +/** + * Submit handler for the display overview form. + */ +function content_display_overview_form_submit($form, &$form_state) { + module_load_include('inc', 'content', 'includes/content.crud'); + $form_values = $form_state['values']; + foreach ($form_values as $key => $values) { + // Groups are handled in fieldgroup_display_overview_form_submit(). + if (in_array($key, $form['#fields'])) { + $field = content_fields($key, $form['#type_name']); + // We have some numeric keys here, so we can't use array_merge. + $field['display_settings'] = $values + $field['display_settings']; + content_field_instance_update($field, FALSE); + } + } + + // Clear caches and rebuild menu. + content_clear_type_cache(TRUE); + menu_rebuild(); + + drupal_set_message(t('Your settings have been saved.')); +} + +/** + * Return an array of field_type options. + */ +function content_field_type_options() { + static $options; + + if (!isset($options)) { + $options = array(); + $field_types = _content_field_types(); + $field_type_options = array(); + foreach ($field_types as $field_type_name => $field_type) { + // skip field types which have no widget types. + if (content_widget_type_options($field_type_name)) { + $options[$field_type_name] = t($field_type['label']); + } + } + asort($options); + } + return $options; +} + +/** + * Return an array of widget type options for a field type. + * + * If no field type is provided, returns a nested array of + * all widget types, keyed by field type human name + */ +function content_widget_type_options($field_type = NULL, $by_label = FALSE) { + static $options; + + if (!isset($options)) { + $options = array(); + foreach (_content_widget_types() as $widget_type_name => $widget_type) { + foreach ($widget_type['field types'] as $widget_field_type) { + $options[$widget_field_type][$widget_type_name] = t($widget_type['label']); + } + } + } + + if ($field_type) { + return !empty($options[$field_type]) ? $options[$field_type] : array(); + } + elseif ($by_label) { + $field_types = _content_field_types(); + $options_by_label = array(); + foreach ($options as $field_type => $widgets) { + $options_by_label[t($field_types[$field_type]['label'])] = $widgets; + } + return $options_by_label; + } + else { + return $options; + } +} + +/** + * Return an array of existing field to be added to a node type. + */ +function content_existing_field_options($type_name) { + $type = content_types($type_name); + $fields = content_fields(); + $field_types = _content_field_types(); + + $options = array(); + foreach ($fields as $field) { + if (!isset($type['fields'][$field['field_name']]) && !$field['locked']) { + $field_type = $field_types[$field['type']]; + $text = t('@type: @field (@label)', array('@type' => t($field_type['label']), '@label' => t($field['widget']['label']), '@field' => $field['field_name'])); + $options[$field['field_name']] = (drupal_strlen($text) > 80) ? truncate_utf8($text, 77) . '...' : $text; + } + } + // Sort the list by type, then by field name, then by label. + asort($options); + + return $options; +} + +/** + * A form element for selecting field, widget, and label. + */ +function content_field_basic_form(&$form_state, $form_values) { + module_load_include('inc', 'content', 'includes/content.crud'); + + $type_name = $form_values['type_name']; + $type = content_types($form_values['type_name']); + $field_name = $form_values['field_name']; + $field_type = $form_values['type']; + $label = $form_values['label']; + + $form = array(); + + $form['basic'] = array( + '#type' => 'fieldset', + '#title' => t('Edit basic information'), + ); + $form['basic']['field_name'] = array( + '#title' => t('Field name'), + '#type' => 'textfield', + '#value' => $field_name, + '#description' => t("The machine-readable name of the field. This name cannot be changed."), + '#disabled' => TRUE, + ); + $form['basic']['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#default_value' => $label, + '#required' => TRUE, + '#description' => t('A human-readable name to be used as the label for this field in the %type content type.', array('%type' => $type['name'])), + ); + $form['basic']['type'] = array( + '#type' => 'select', + '#title' => t('Field type'), + '#options' => content_field_type_options(), + '#default_value' => $field_type, + '#description' => t('The type of data you would like to store in the database with this field. This option cannot be changed.'), + '#disabled' => TRUE, + ); + $form['basic']['widget_type'] = array( + '#type' => 'select', + '#title' => t('Widget type'), + '#required' => TRUE, + '#options' => content_widget_type_options($field_type), + '#default_value' => $form_values['widget_type'], + '#description' => t('The type of form element you would like to present to the user when creating this field in the %type content type.', array('%type' => $type['name'])), + ); + + $form['type_name'] = array( + '#type' => 'value', + '#value' => $type_name, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Continue'), + ); + + $form['#validate'] = array(); + $form['#submit'] = array('content_field_basic_form_submit'); + + return $form; +} + +/** + * Create a new field for a content type. + */ +function content_field_basic_form_submit($form, &$form_state) { + $form_values = $form_state['values']; + + $label = $form_values['label']; + + // Set the right module information + $field_types = _content_field_types(); + $widget_types = _content_widget_types(); + $form_values['module'] = $field_types[$form_values['type']]['module']; + $form_values['widget_module'] = $widget_types[$form_values['widget_type']]['module']; + + // Make sure we retain previous values and only over-write changed values. + module_load_include('inc', 'content', 'includes/content.crud'); + $instances = content_field_instance_read(array('field_name' => $form_values['field_name'], 'type_name' => $form_values['type_name'])); + $field = array_merge(content_field_instance_collapse($instances[0]), $form_values); + if (content_field_instance_update($field)) { + drupal_set_message(t('Updated basic settings for field %label.', array( + '%label' => $label))); + } + else { + drupal_set_message(t('There was a problem updating the basic settings for field %label.', array( + '%label' => $label))); + } + + $type = content_types($form_values['type_name']); + $form_state['redirect'] = 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $form_values['field_name']; + $form_state['rebuild'] = FALSE; +} + +/** + * Menu callback; present a form for removing a field from a content type. + */ +function content_field_remove_form(&$form_state, $type_name, $field_name) { + $type = content_types($type_name); + $field = $type['fields'][$field_name]; + + $form = array(); + $form['type_name'] = array( + '#type' => 'value', + '#value' => $type_name, + ); + $form['field_name'] = array( + '#type' => 'value', + '#value' => $field_name, + ); + + $output = confirm_form($form, + t('Are you sure you want to remove the field %field?', array('%field' => $field['widget']['label'])), + 'admin/content/node-type/'. $type['url_str'] .'/fields', + t('If you have any content left in this field, it will be lost. This action cannot be undone.'), + t('Remove'), t('Cancel'), + 'confirm' + ); + + if ($field['locked']) { + unset($output['actions']['submit']); + $output['description']['#value'] = t('This field is <strong>locked</strong> and cannot be removed.'); + } + + return $output; +} + +/** + * Remove a field from a content type. + */ +function content_field_remove_form_submit($form, &$form_state) { + module_load_include('inc', 'content', 'includes/content.crud'); + $form_values = $form_state['values']; + + $type = content_types($form_values['type_name']); + $field = $type['fields'][$form_values['field_name']]; + if ($field['locked']) { + return; + } + + if ($type && $field && $form_values['confirm']) { + if (content_field_instance_delete($form_values['field_name'], $form_values['type_name'])) { + drupal_set_message(t('Removed field %field from %type.', array( + '%field' => $field['widget']['label'], + '%type' => $type['name']))); + } + else { + drupal_set_message(t('There was a problem deleting %field from %type.', array( + '%field' => $field['widget']['label'], + '%type' => $type['name']))); + } + $form_state['redirect'] = 'admin/content/node-type/'. $type['url_str'] .'/fields'; + } +} + +/** + * Menu callback; presents the field editing page. + */ +function content_field_edit_form(&$form_state, $type_name, $field_name) { + $output = ''; + $type = content_types($type_name); + $field = $type['fields'][$field_name]; + + if ($field['locked']) { + $output = array(); + $output['locked'] = array( + '#value' => t('The field %field is locked and cannot be edited.', array('%field' => $field['widget']['label'])), + ); + return $output; + } + + $field_types = _content_field_types(); + $field_type = $field_types[$field['type']]; + $widget_types = _content_widget_types(); + $widget_type = $widget_types[$field['widget']['type']]; + + $title = isset($field['widget']['label']) ? $field['widget']['label'] : $field['field_name']; + drupal_set_title(check_plain($title)); + + // See if we need to change the widget type or label. + if (isset($form_state['change_basic'])) { + module_load_include('inc', 'content', 'includes/content.crud'); + $field_values = content_field_instance_collapse($field); + return content_field_basic_form($form_state, $field_values); + } + + $add_new_sequence = isset($_REQUEST['destinations']); + + // Remove menu tabs when we are in an 'add new' sequence. + if ($add_new_sequence) { + menu_set_item(NULL, menu_get_item('node')); + } + + $form = array(); + $form['#field'] = $field; + $form['#type'] = $type; + + // Basic iformation : hide when we are in an 'add new' sequence. + $form['basic'] = array( + '#type' => 'fieldset', + '#title' => t('%type basic information', array('%type' => $type['name'])), + '#access' => !$add_new_sequence, + ); + $form['basic']['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#value' => $field['widget']['label'], + '#disabled' => TRUE, + ); + $form['basic']['field_name'] = array( + '#type' => 'hidden', + '#title' => t('Field name'), + '#value' => $field['field_name'], + '#disabled' => TRUE, + ); + $form['basic']['type'] = array( + '#type' => 'hidden', + '#title' => t('Field type'), + '#value' => $field['type'], + '#disabled' => TRUE, + ); + $widget_options = content_widget_type_options($field['type']); + $form['basic']['widget_type'] = array( + '#type' => 'select', + '#title' => t('Widget type'), + '#options' => $widget_options, + '#default_value' => $field['widget']['type'] ? $field['widget']['type'] : key($widget_options), + '#disabled' => TRUE, + ); + $form['basic']['change'] = array( + '#type' => 'submit', + '#value' => t('Change basic information'), + '#submit' => array('content_field_edit_form_submit_update_basic'), + ); + + $form['widget'] = array( + '#type' => 'fieldset', + '#title' => t('%type settings', array('%type' => $type['name'])), + '#description' => t('These settings apply only to the %field field as it appears in the %type content type.', array( + '%field' => $field['widget']['label'], + '%type' => $type['name'])), + ); + $form['widget']['weight'] = array( + '#type' => 'hidden', + '#default_value' => $field['widget']['weight'], + ); + + $additions = (array) module_invoke($widget_type['module'], 'widget_settings', 'form', $field['widget']); + drupal_alter('widget_settings', $additions, 'form', $field['widget']); + $form['widget'] = array_merge($form['widget'], $additions); + + $form['widget']['description'] = array( + '#type' => 'textarea', + '#title' => t('Help text'), + '#default_value' => $field['widget']['description'], + '#rows' => 5, + '#description' => t('Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags', array('@tags' => _content_filter_xss_display_allowed_tags())), + '#required' => FALSE, + ); + + // Add handling for default value if not provided by field. + if (content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) { + + // Store the original default value for use in programmed forms. + // Set '#default_value' instead of '#value' so programmed values + // can override whatever we set here. + $default_value = isset($field['widget']['default_value']) ? $field['widget']['default_value'] : array(); + $default_value_php = isset($field['widget']['default_value_php']) ? $field['widget']['default_value_php'] : ''; + $form['widget']['default_value'] = array( + '#type' => 'value', + '#default_value' => $default_value, + ); + $form['widget']['default_value_php'] = array( + '#type' => 'value', + '#default_value' => $default_value_php, + ); + + // We can't tell at the time we build the form if this is a programmed + // form or not, so we always end up adding the default value widget + // even if we won't use it. + $form['widget']['default_value_fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Default value'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + // Default value widget. + $widget_form = array('#node' => (object) array('type' => $type_name)); + $widget_form_state = array('values' => array($field['field_name'] => $default_value)); + // Make sure the default value is not a required field. + $widget_field = $field; + $widget_field['required'] = FALSE; + module_load_include('inc', 'content', 'includes/content.node_form'); + $form_element = content_field_form($widget_form, $widget_form_state, $widget_field, 0); + $form['widget']['default_value_fieldset']['default_value_widget'] = $form_element; + $form['widget']['default_value_fieldset']['default_value_widget']['#tree'] = TRUE; + // Set up form info that the default value widget will need to find in the form. + $form['#field_info'] = array($widget_field['field_name'] => $widget_field); + + // Advanced: PHP code. + $form['widget']['default_value_fieldset']['advanced_options'] = array( + '#type' => 'fieldset', + '#title' => t('PHP code'), + '#collapsible' => TRUE, + '#collapsed' => empty($field['widget']['default_value_php']), + ); + + if (user_access('Use PHP input for field settings (dangerous - grant with care)')) { + $db_info = content_database_info($field); + $columns = array_keys($db_info['columns']); + foreach ($columns as $key => $column) { + $columns[$key] = t("'@column' => value for @column", array('@column' => $column)); + } + $sample = t("return array(\n 0 => array(@columns),\n // You'll usually want to stop here. Provide more values\n // if you want your 'default value' to be multi-valued:\n 1 => array(@columns),\n 2 => ...\n);", array('@columns' => implode(', ', $columns))); + + $form['widget']['default_value_fieldset']['advanced_options']['default_value_php'] = array( + '#type' => 'textarea', + '#title' => t('Code'), + '#default_value' => isset($field['widget']['default_value_php']) ? $field['widget']['default_value_php'] : '', + '#rows' => 6, + '#tree' => TRUE, + '#description' => t('Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>To figure out the expected format, you can use the <em>devel load</em> tab provided by <a href="@link_devel">devel module</a> on a %type content page.', array( + '!sample' => $sample, + '@link_devel' => 'http://www.drupal.org/project/devel', + '%type' => $type_name)), + ); + } + else { + $form['widget']['default_value_fieldset']['advanced_options']['markup_default_value_php'] = array( + '#type' => 'item', + '#title' => t('Code'), + '#value' => !empty($field['widget']['default_value_php']) ? '<code>'. check_plain($field['widget']['default_value_php']) .'</code>' : t('<none>'), + '#description' => empty($field['widget']['default_value_php']) ? t("You're not allowed to input PHP code.") : t('This PHP code was set by an administrator and will override any value specified above.'), + ); + } + } + + $form['field'] = array( + '#type' => 'fieldset', + '#title' => t('Global settings'), + '#description' => t('These settings apply to the %field field in every content type in which it appears.', array('%field' => $field['widget']['label'])), + ); + $form['field']['required'] = array( + '#type' => 'checkbox', + '#title' => t('Required'), + '#default_value' => $field['required'], + ); + $description = t('Maximum number of values users can enter for this field.'); + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) { + $description .= '<br/>'. t("'Unlimited' will provide an 'Add more' button so the users can add as many values as they like."); + } + $description .= '<br/><strong>'. t('Warning! Changing this setting after data has been created could result in the loss of data!') .'</strong>'; + $form['field']['multiple'] = array( + '#type' => 'select', + '#title' => t('Number of values'), + '#options' => array(1 => t('Unlimited'), 0 => 1) + drupal_map_assoc(range(2, 10)), + '#default_value' => $field['multiple'], + '#description' => $description, + ); + + $form['field']['previous_field'] = array( + '#type' => 'hidden', + '#value' => serialize($field), + ); + + $additions = (array) module_invoke($field_type['module'], 'field_settings', 'form', $field); + drupal_alter('field_settings', $additions, 'form', $field); + $form['field'] = array_merge($form['field'], $additions); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save field settings'), + ); + $form['type_name'] = array( + '#type' => 'value', + '#value' => $type_name, + ); + $form['field_name'] = array( + '#type' => 'value', + '#value' => $field_name, + ); + $form['type'] = array( + '#type' => 'value', + '#value' => $field['type'], + ); + $form['module'] = array( + '#type' => 'value', + '#value' => $field['module'], + ); + $form['widget']['label'] = array( + '#type' => 'value', + '#value' => $field['widget']['label'], + ); + $form['widget_module'] = array( + '#type' => 'value', + '#value' => $field['widget']['module'], + ); + $form['columns'] = array( + '#type' => 'value', + '#value' => $field['columns'], + ); + return $form; +} + +/** + * Validate a field's settings. + */ +function content_field_edit_form_validate($form, &$form_state) { + $form_values = $form_state['values']; + if (isset($form_state['change_basic']) || $form_values['op'] == t('Change basic information')) { + return; + } + + module_load_include('inc', 'content', 'includes/content.crud'); + $previous_field = unserialize($form_values['previous_field']); + $field = content_field_instance_expand($form_values); + $field['db_storage'] = content_storage_type($field); + + $field_types = _content_field_types(); + $field_type = $field_types[$field['type']]; + $widget_types = _content_widget_types(); + $widget_type = $widget_types[$field['widget']['type']]; + + if ($dropped_data = content_alter_db_analyze($previous_field, $field)) { + // @TODO + // This is a change that might result in loss of data. + // Add a confirmation form here. + // dsm($dropped_data); + } + + module_invoke($widget_type['module'], 'widget_settings', 'validate', array_merge($field, $form_values)); + module_invoke($field_type['module'], 'field_settings', 'validate', array_merge($field, $form_values)); + + // If content.module is handling the default value, + // validate the result using the field validation. + if (content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) { + + // If this is a programmed form, get rid of the default value widget, + // we have the default values already. + if ($form['#programmed']) { + form_set_value(array('#parents' => array('default_value_widget')), NULL, $form_state); + return; + } + + if (isset($form_values['default_value_php']) && + ($php = trim($form_values['default_value_php']))) { + $error = FALSE; + ob_start(); + $return = eval($php); + ob_end_clean(); + if (!is_array($return)) { + $error = TRUE; + } + else { + foreach ($return as $item) { + if (!is_array($item)) { + $error = TRUE; + break; + } + } + } + if ($error) { + $db_info = content_database_info($field); + $columns = array_keys($db_info['columns']); + foreach ($columns as $key => $column) { + $columns[$key] = t("'@column' => value for @column", array('@column' => $column)); + } + $sample = t("return array(\n 0 => array(@columns),\n // You'll usually want to stop here. Provide more values\n // if you want your 'default value' to be multi-valued:\n 1 => array(@columns),\n 2 => ...\n);", array('@columns' => implode(', ', $columns))); + + form_set_error('default_value_php', t('The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value', array( + '!sample' => $sample, + '@value' => print_r($return, TRUE)))); + return; + } + else { + $default_value = $return; + $is_code = TRUE; + form_set_value(array('#parents' => array('default_value_php')), $php, $form_state); + form_set_value(array('#parents' => array('default_value')), array(), $form_state); + } + } + elseif (!empty($form_values['default_value_widget'])) { + // Fields that handle their own multiple values may use an expected + // value as the top-level key, so just pop off the top element. + $key = array_shift(array_keys($form_values['default_value_widget'])); + $default_value = $form_values['default_value_widget'][$key]; + $is_code = FALSE; + form_set_value(array('#parents' => array('default_value_php')), '', $form_state); + form_set_value(array('#parents' => array('default_value')), $default_value, $form_state); + } + if (isset($default_value)) { + $node = array(); + $node[$form_values['field_name']] = $default_value; + $field['required'] = FALSE; + $field_function = $field_type['module'] .'_field'; + + $errors_before = form_get_errors(); + + // Widget now does its own validation, should be no need + // to add anything for widget validation here. + if (function_exists($field_function)) { + $field_function('validate', $node, $field, $default_value, $form, NULL); + } + // The field validation routine won't set an error on the right field, + // so set it here. + $errors_after = form_get_errors(); + if (count($errors_after) > count($errors_before)) { + if (trim($form_values['default_value_php'])) { + form_set_error('default_value_php', t("The PHP code for 'default value' returned @value, which is invalid.", array( + '@value' => print_r($default_value, TRUE)))); + } + else { + form_set_error('default_value', t('The default value is invalid.')); + } + } + } + } +} + +/** + * Button submit handler. + */ +function content_field_edit_form_submit_update_basic($form, &$form_state) { + $form_state['change_basic'] = TRUE; + $form_state['rebuild'] = TRUE; +} + +/** + * Save a field's settings after editing. + */ +function content_field_edit_form_submit($form, &$form_state) { + module_load_include('inc', 'content', 'includes/content.crud'); + $form_values = $form_state['values']; + content_field_instance_update($form_values); + + $destinations = !empty($_REQUEST['destinations']) ? $_REQUEST['destinations'] : array(); + // Remove any external URLs. + $destinations = array_diff($destinations, array_filter($destinations, 'menu_path_is_external')); + if ($destinations) { + drupal_set_message(t('Added field %label.', array('%label' => $form_values['label']))); + $form_state['redirect'] = content_get_destinations($destinations); + } + else { + drupal_set_message(t('Saved field %label.', array('%label' => $form_values['label']))); + $type = content_types($form_values['type_name']); + $form_state['redirect'] = 'admin/content/node-type/'. $type['url_str'] .'/fields'; + } +} + +/** + * Helper function to handle multipage redirects. + */ +function content_get_destinations($destinations) { + $query = array(); + $path = array_shift($destinations); + if ($destinations) { + $query['destinations'] = $destinations; + } + return array($path, $query); +} + +/** + * Content Schema Alter + * + * Alter the database schema. + * + * TODO figure out an API-safe way to use batching to update the nodes that + * will be affected by this change so the node_save() hooks will fire. + * + */ +function content_alter_schema($previous_field, $new_field) { + content_alter_db($previous_field, $new_field); +} + +/** + * Schema Alter Analyze + * + * Analyze if changes will remove columns or delta values, thus losing data. + * Do this so we can delete the data and fire the necessary hooks, before + * we actually alter the schema. + */ +function content_alter_db_analyze($previous_field, $new_field) { + $dropped = array(); + // There is no loss of data if there was no previous data. + if (empty($previous_field)) { + return $dropped; + } + + // Analyze possible data loss from changes in storage type. + if (!empty($previous_field) && !empty($new_field)) { + // Changing from multiple to not multiple data, will cause loss of all + // values greater than zero. + if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD && + $new_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE) { + $dropped['delta'] = 0; + } + // Changing from one multiple value to another will cause loss of all + // values for deltas greater than or equal to the new multiple value. + elseif (isset($previous_field['multiple']) && isset($new_field['multiple'])) { + if ($previous_field['multiple'] > $new_field['multiple'] && + $new_field['multiple'] > 1) { + $dropped['delta'] = $new_field['multiple']; + } + } + } + + // Analyze possible data loss from changes in field columns. + $previous_schema = !empty($previous_field) ? content_table_schema($previous_field) : array('fields' => array()); + $new_schema = !empty($new_field) ? content_table_schema($new_field) : array('fields' => array()); + $dropped_columns = array_diff(array_keys($previous_schema['fields']), array_keys($new_schema['fields'])); + if ($dropped_columns) { + $dropped['columns'] = $dropped_columns; + } +// if (empty($new_schema['fields'])) { +// // No new columns, will lose all columns for a field. +// foreach ($previous_schema['fields'] as $column => $attributes) { +// $dropped['columns'][] = $column; +// } +// } +// else { +// // Check both old and new columns to see if we are deleting some columns for a field. +// foreach ($previous_schema['fields'] as $column => $attributes) { +// if (!isset($new_schema['fields'][$column])) { +// $dropped['columns'][] = $column; +// } +// } +// } + + return $dropped; +} + +/** + * Perform adds, alters, and drops as needed to synchronize the database with + * new field definitions. + */ +function content_alter_db($previous_field, $new_field) { + $ret = array(); + + // One or the other of these must be valid. + if (empty($previous_field) && empty($new_field)) { + return $ret; + } + + // Gather relevant information : schema, table name... + $previous_schema = !empty($previous_field) ? content_table_schema($previous_field) : array(); + $new_schema = !empty($new_field) ? content_table_schema($new_field) : array(); + if (!empty($previous_field)) { + $previous_db_info = content_database_info($previous_field); + $previous_table = $previous_db_info['table']; + } + if (!empty($new_field)) { + $new_db_info = content_database_info($new_field); + $new_table = $new_db_info['table']; + } + + // Deletion of a field instance: drop relevant columns and tables and return. + if (empty($new_field)) { + if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) { + db_drop_table($ret, $previous_table); + } + else { + foreach ($previous_schema['fields'] as $column => $attributes) { + if (!in_array($column, array('nid', 'vid', 'delta'))) { + db_drop_field($ret, $previous_table, $column); + } + } + } + content_alter_db_cleanup(); + return $ret; + } + + // Check that content types that have fields do have a per-type table. + if (!empty($new_field)) { + $base_tablename = _content_tablename($new_field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + if (!db_table_exists($base_tablename)) { + db_create_table($ret, $base_tablename, content_table_schema()); + } + } + + // Create new table and columns, if not already created. + if (!db_table_exists($new_table)) { + db_create_table($ret, $new_table, $new_schema); + } + else { + // Or add fields and/or indexes to an existing table. + foreach ($new_schema['fields'] as $column => $attributes) { + if (!in_array($column, array('nid', 'vid', 'delta'))) { + // Create the column if it does not exist. + if (!db_column_exists($new_table, $column)) { + db_add_field($ret, $new_table, $column, $attributes); + } + // Create the index if requested to, and it does not exist. + if (isset($new_schema['indexes'][$column]) && !content_db_index_exists($new_table, $column)) { + db_add_index($ret, $new_table, $column, $new_schema['indexes'][$column]); + } + } + } + } + + // If this is a new field, we're done. + if (empty($previous_field)) { + content_alter_db_cleanup(); + return $ret; + } + + // If the previous table doesn't exist, we're done. + // Could happen if someone tries to run a schema update from an + // content.install update function more than once. + if (!db_table_exists($previous_table)) { + content_alter_db_cleanup(); + return $ret; + } + + // If changing data from one schema to another, see if changes require that + // we drop multiple values or migrate data from one storage type to another. + $migrate_columns = array_intersect_assoc($new_schema['fields'], $previous_schema['fields']); + unset($migrate_columns['nid'], $migrate_columns['vid'], $migrate_columns['delta']); + + // If we're going from one multiple value a smaller one or to single, + // drop all delta values higher than the new maximum delta value. + // Not needed if the new multiple is unlimited or if the new table is the content table. + if ($new_table != $base_tablename && $new_field['multiple'] < $previous_field['multiple'] && $new_field['multiple'] != 1) { + db_query("DELETE FROM {". $new_table ."} WHERE delta >= ". max(1, $new_field['multiple'])); + } + + // If going from multiple to non-multiple, make sure the field tables have + // the right database structure to accept migrated data. + if ($new_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) { + if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD && count($previous_schema['fields'])) { + // Already using per-field storage; change multiplicity if needed. + if ($previous_field['multiple'] > 0 && $new_field['multiple'] == 0) { + db_drop_field($ret, $new_table, 'delta'); + db_drop_primary_key($ret, $new_table); + db_add_primary_key($ret, $new_table, array('vid')); + } + else if ($previous_field['multiple'] == 0 && $new_field['multiple'] > 0) { + db_add_field($ret, $new_table, 'delta', array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0)); + db_drop_primary_key($ret, $new_table); + db_add_primary_key($ret, $new_table, array('vid', 'delta')); + } + } + } + + // Migrate data from per-content-type storage. + if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && + $new_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) { + $columns = array_keys($migrate_columns); + if ($new_field['multiple']) { + db_query('INSERT INTO {'. $new_table .'} (vid, nid, delta, '. implode(', ', $columns) .') '. + ' SELECT vid, nid, 0, '. implode(', ', $columns) .' FROM {'. $previous_table .'}'); + } + else { + db_query('INSERT INTO {'. $new_table .'} (vid, nid, '. implode(', ', $columns) .') '. + ' SELECT vid, nid, '. implode(', ', $columns) .' FROM {'. $previous_table .'}'); + } + foreach ($columns as $column_name) { + db_drop_field($ret, $previous_table, $column_name); + } + } + + // Migrate data from per-field storage, and drop per-field table. + if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD && + $new_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE) { + // In order to be able to use drupal_write_record, we need to + // rebuild the schema now. + content_alter_db_cleanup(); + if ($previous_field['multiple']) { + $result = db_query("SELECT * FROM {". $previous_table ."} c JOIN {node} n ON c.nid = n.nid WHERE delta = 0 AND n.type = '%s'", $new_field['type_name']); + } + else { + $result = db_query("SELECT * FROM {". $previous_table ."} c JOIN {node} n ON c.nid = n.nid WHERE n.type = '%s'", $new_field['type_name']); + } + $record = array(); + while ($data = db_fetch_array($result)) { + $record['nid'] = $data['nid']; + $record['vid'] = $data['vid']; + if ($previous_field['multiple']) { + $record['delta'] = $data['delta']; + } + foreach ($migrate_columns as $column => $attributes) { + if (is_null($data[$column])) { + $record[$column] = NULL; + } + else { + $record[$column] = $data[$column]; + // Prevent double serializtion in drupal_write_record. + if (isset($attributes['serialize']) && $attributes['serialize']) { + $record[$column] = unserialize($record[$column]); + } + } + } + if (db_result(db_query('SELECT COUNT(*) FROM {'. $new_table . + '} WHERE vid = %d AND nid = %d', $data['vid'], $data['nid']))) { + $keys = $new_field['multiple'] ? array('vid', 'delta') : array('vid'); + drupal_write_record($new_table, $record, $keys); + } + else { + drupal_write_record($new_table, $record); + } + } + db_drop_table($ret, $previous_table); + } + + // Change modified columns that don't involve storage changes. + foreach ($new_schema['fields'] as $column => $attributes) { + if (isset($previous_schema['fields'][$column]) && + $previous_field['db_storage'] == $new_field['db_storage']) { + if ($attributes != $previous_schema['fields'][$column]) { + if (!in_array($column, array('nid', 'vid', 'delta'))) { + db_change_field($ret, $new_table, $column, $column, $attributes); + } + } + } + } + + // Remove obsolete columns. + foreach ($previous_schema['fields'] as $column => $attributes) { + if (!isset($new_schema['fields'][$column])) { + if (!in_array($column, array('nid', 'vid', 'delta'))) { + db_drop_field($ret, $previous_table, $column); + } + } + } + + // TODO: debugging stuff - should be removed + if (module_exists('devel')) { + //dsm($ret); + } + return $ret; +} + +/** + * Helper function for handling cleanup operations when schema changes are made. + */ +function content_alter_db_cleanup() { + // Rebuild the whole database schema. + // TODO: this could be optimized. We don't need to rebuild in *every case*... + // Or do we? This affects the schema and menu and may have unfortunate + // delayed effects if we don't clear everything out at this point. + content_clear_type_cache(TRUE); +} + +/** + * Helper function to order fields and groups when theming (preprocessing) + * overview forms. + * + * The $form is passed by reference because we assign depths as parenting + * relationships are sorted out. + */ +function _content_overview_order(&$form, $field_rows, $group_rows) { + // Put weight and parenting values into a $dummy render structure + // and let drupal_render figure out the corresponding row order. + $dummy = array(); + // Group rows: account for weight. + if (module_exists('fieldgroup')) { + foreach ($group_rows as $name) { + $dummy[$name] = array('#weight' => $form[$name]['weight']['#value'], '#value' => $name .' '); + } + } + // Field rows : account for weight and parenting. + foreach ($field_rows as $name) { + $dummy[$name] = array('#weight' => $form[$name]['weight']['#value'], '#value' => $name .' '); + if (module_exists('fieldgroup')) { + if ($parent = $form[$name]['parent']['#value']) { + $form[$name]['#depth'] = 1; + $dummy[$parent][$name] = $dummy[$name]; + unset($dummy[$name]); + } + } + } + return $dummy ? explode(' ', trim(drupal_render($dummy))) : array(); +} + +/** + * Batching process for changing the field schema, + * running each affected node through node_save() first, to + * fire all hooks. + * + * TODO This is just a placeholder for now because batching can't be safely + * used with API hooks. Need to come back and figure out how to incorporate + * this and get it working properly when the fields are altered via the API. + */ +function content_alter_fields($previous_field, $new_field) { + // See what values need to be updated in the field data. + $mask = content_alter_db_mask($previous_field, $new_field); + + // We use batch processing to prevent timeout when updating a large number + // of nodes. If there is no previous data to adjust, we can just go straight + // to altering the schema, otherwise use batch processing to update + // the database one node at a time, then update the schema. + if (empty($mask)) { + return content_alter_db($previous_field, $new_field); + } + $updates = array( + 'mask' => $mask['mask'], + 'alt_mask' => $mask['alt_mask'], + 'delta' => $mask['delta'], + ); + $batch = array( + 'operations' => array( + array('content_field_batch_update', array($previous_field['field_name'] => $updates)), + array('content_alter_db', array($previous_field, $new_field)) + ), + 'finished' => '_content_alter_fields_finished', + 'title' => t('Processing'), + 'error_message' => t('The update has encountered an error.'), + 'file' => './'. drupal_get_path('module', 'content') .'/includes/content.admin.inc', + ); + batch_set($batch); + if (!empty($url)) { + batch_process($url, $url); + } +} + +/** + * Content Replace Fields 'finished' callback. + */ +function _content_alter_fields_finished($success, $results, $operations) { + if ($success) { + drupal_set_message(t('The database has been altered and data has been migrated or deleted.')); + } + else { + drupal_set_message(t('An error occurred and database alteration did not complete.'), 'error'); + $message = format_plural(count($results), '1 item successfully processed:', '@count items successfully processed:'); + $message .= theme('item_list', $results); + drupal_set_message($message); + } +} + +/** + * Create a mask for the column data that should be deleted in each field. + * + * This is a bit tricky. We could theoretically have some columns + * that should be set to empty and others with valid info that should + * not be emptied out. But if delta values > X are to be wiped out, they + * need to wipe out even columns that still have values. And the NULL + * values in these columns after the alteration may be enough to make + * the item 'empty', as defined by hook_content_is_empty(), even if + * some columns still have values, so all these things need to be tested. + */ +function content_alter_db_mask($previous_field, $new_field) { + // Get an array of column values that will be dropped by this + // schema change and create a mask to feed to content_batch_update. + + $dropped = content_alter_db_analyze($previous_field, $new_field); + if (empty($dropped)) { + return array(); + } + $mask = array('mask' => array()); + foreach (array_keys($previous_field['columns']) as $column_name) { + // The basic mask will empty the dropped columns. + if (isset($dropped['columns']) && in_array($column_name, $dropped['columns'])) { + $mask['mask'][$column_name] = NULL; + } + // Over the delta we'll empty all columns. + if (isset($dropped['delta'])) { + $mask['alt_mask'][$column_name] = NULL; + } + } + if (isset($dropped['delta'])) { + $mask['delta'] = $dropped['delta']; + } + return $mask; +} + +/** + * Content Field Batch Update Operation + * + * Find all nodes that contain a field and update their values. + * + * @param $updates + * an array like: + * 'field_name' => array( + * 'mask' => array() + * // Keyed array of column names and replacement values for use + * // below delta, or for all values if no delta is supplied. + * 'alt_mask' => array() + * // Optional, keyed array of column names and replacement values for use + * // at or above delta, if a delta is supplied. + * 'delta' => # + * // Optional, the number to use as the delta value where you switch from + * // one mask to the other. + * ), + */ +function content_field_batch_update($updates, &$context) { + if (empty($field)) { + $context['finished'] = 1; + return; + } + $field_name = $updates['field_name']; + $field = content_fields($field_name); + + if (!isset($context['sandbox']['progress'])) { + $db_info = content_database_info($field); + + // Might run into non-existent tables when cleaning up a corrupted + // database, like some of the old content storage changes in the + // .install files. + if (!db_table_exists($db_info['table'])) { + return $context['finished'] = 1; + } + $nodes = array(); + $result = db_query("SELECT nid FROM {". $db_info['table'] ."}"); + while ($node = db_fetch_array($result)) { + $nodes[] = $node['nid']; + } + $context['sandbox']['progress'] = 0; + $context['sandbox']['max'] = count($nodes); + $context['sandbox']['nodes'] = $nodes; + } + + // Process nodes by groups of 5. + $count = min(5, count($context['sandbox']['nodes'])); + + for ($i = 1; $i <= $count; $i++) { + // For each nid, load the node, empty the column values + // or the whole field, and re-save it. + $nid = array_shift($context['sandbox']['nodes']); + $node = content_field_replace($nid, array($updates)); + + // Store result for post-processing in the finished callback. + $context['results'][] = l($node->title, 'node/'. $node->nid); + + // Update our progress information. + $context['sandbox']['progress']++; + $context['message'] = t('Processing %title', array('%title' => $node->title)); + } + + // Inform the batch engine that we are not finished, + // and provide an estimation of the completion level we reached. + if ($context['sandbox']['progress'] != $context['sandbox']['max']) { + $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max']; + } +} + +/** + * Content Field Replace + * + * Replace field values in a node from an array of update values. + * + * Supply an array of one or more fields and masks of field column values + * to be replaced into field values, one mask for basic values and an optional + * different mask for values in field items equal to or higher than a + * specified delta. + * + * The masks should contain only the column values to be substituted in. + * The supplied values will be merged into the existing values to replace + * only the values in the mask, leaving all other values unchanged. + * + * The ability to set different masks starting at a delta allows the + * possibility of setting values above a certain delta to NULL prior + * to altering the database schema. + * + * @param $nid + * @param $updates + * an array like: + * 'field_name' => array( + * 'mask' => array() + * // Keyed array of column names and replacement values for use + * // below delta, or for all values if no delta is supplied. + * 'alt_mask' => array() + * // Optional, keyed array of column names and replacement values for use + * // at or above delta, if a delta is supplied. + * 'delta' => # + * // Optional, the number to use as the delta value where you switch from + * // one mask to the other. + * ), + */ +function content_field_replace($nid, $updates) { + $node = node_load($nid, NULL, TRUE); + foreach ($updates as $field_name => $update) { + $items = isset($node->$field_name) ? $node->$field_name : array(); + foreach ($items as $delta => $value) { + $field_mask = (isset($update['delta']) && isset($update['alt_mask']) && $delta >= $update['delta']) ? $update['alt_mask'] : $mask['mask']; + // Merge the mask into the field values to do the replacements. + $items[$delta] = array_merge($items[$delta], $field_mask); + } + // Test if the new values will make items qualify as empty. + $items = content_set_empty($field, $items); + $node->$field_name = $items; + } + node_save($node); + return $node; +} + +/** + * Helper form element validator : integer. + */ +function _element_validate_integer($element, &$form_state) { + $value = $element['#value']; + if ($value !== '' && (!is_numeric($value) || intval($value) != $value)) { + form_error($element, t('%name must be an integer.', array('%name' => $element['#title']))); + } +} + +/** + * Helper form element validator : integer > 0. + */ +function _element_validate_integer_positive($element, &$form_state) { + $value = $element['#value']; + if ($value !== '' && (!is_numeric($value) || intval($value) != $value || $value <= 0)) { + form_error($element, t('%name must be a positive integer.', array('%name' => $element['#title']))); + } +} + +/** + * Helper form element validator : number. + */ +function _element_validate_number($element, &$form_state) { + $value = $element['#value']; + if ($value != '' && !is_numeric($value)) { + form_error($element, t('%name must be a number.', array('%name' => $element['#title']))); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.crud.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.crud.inc new file mode 100644 index 0000000000000000000000000000000000000000..2942940eaf6628d6f5dee33baa0e6d9bb4959257 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.crud.inc @@ -0,0 +1,695 @@ +<?php +// $Id$ + +/** + * @file + * Create/Read/Update/Delete functions for CCK-defined object types. + * + * The content module field API will allow $field arguments to + * be input either in the field => widget nested array that is used + * by the content module, or in flattened $form_values arrays, by + * converting flattened arrays to the nested format. + * + * A hook_content_fieldapi() is available for each field instance action, + * and each hook receives the nested field => widget array as an argument. + * + * The hook_content_fieldapi() $ops include: + * + * - create instance + * - read instance + * - update instance + * - delete instance + * + * Another function, content_module_delete($module) will clean up + * after a module that has been deleted by removing all data and + * settings information that was created by that module. + */ + +/** + * Create an array of default values for a field type. + */ +function content_field_default_values($field_type) { + $field_types = _content_field_types(); + $module = $field_types[$field_type]['module']; + + $field = array( + 'module' => $module, + 'type' => $field_type, + 'active' => 0, + ); + + if (module_exists($module)) { + $field['active'] = 1; + } + + $field['columns'] = (array) module_invoke($module, 'field_settings', 'database columns', $field); + // Ensure columns always default to NULL values. + foreach ($field['columns'] as $column_name => $column) { + $field['columns'][$column_name]['not null'] = FALSE; + } + + $field['required'] = 0; + $field['multiple'] = 0; + $field['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE; + + // Make sure field settings all have an index in the array. + $setting_names = (array) module_invoke($module, 'field_settings', 'save', $field); + drupal_alter('field_settings', $setting_names, 'save', $field); + foreach ($setting_names as $setting) { + $field[$setting] = NULL; + } + return $field; +} + +/** + * Create an array of default values for a field instance. + */ +function content_instance_default_values($field_name, $type_name, $widget_type) { + $widget_types = _content_widget_types(); + $module = $widget_types[$widget_type]['module']; + + $widget = array( + 'field_name' => $field_name, + 'type_name' => $type_name, + 'weight' => 0, + 'label' => $field_name, + 'description' => '', + 'widget_type' => $widget_type, + 'widget_module' => $module, + 'display_settings' => array(), + 'widget_settings' => array(), + ); + + if (module_exists($module)) { + $widget['widget_active'] = 1; + } + + $settings_names = array_merge(array('label'), array_keys(content_build_modes())); + $widget['display_settings'] = array(); + foreach ($settings_names as $name) { + $widget['display_settings'][$name]['format'] = ($name == 'label') ? 'above' : 'default'; + $widget['display_settings'][$name]['exclude'] = 0; + } + + // Make sure widget settings all have an index in the array. + $settings_names = (array) module_invoke($module, 'widget_settings', 'save', $widget); + drupal_alter('widget_settings', $settings_names, 'save', $widget); + $widget['widget_settings'] = array(); + foreach ($settings_names as $name) { + $widget['widget_settings'][$name] = NULL; + } + return $widget; +} + +/** + * Expand field info to create field => widget info. + */ +function content_field_instance_expand($field) { + if (isset($field['widget'])) { + return $field; + } + $field['widget'] = !empty($field['widget_settings']) ? $field['widget_settings'] : array(); + $field['widget']['label'] = !empty($field['label']) ? $field['label'] : $field['field_name']; + $field['widget']['weight'] = !empty($field['weight']) ? $field['weight'] : 0; + $field['widget']['description'] = !empty($field['description']) ? $field['description'] : ''; + + if (!empty($field['widget_type'])) { + $field['widget']['type'] = $field['widget_type']; + $widget_types = _content_widget_types(); + $field['widget']['module'] = isset($widget_types[$field['widget_type']]['module']) ? $widget_types[$field['widget_type']]['module'] : $field['widget_module']; + } + elseif (!empty($field['widget_module'])) { + $field['widget']['module'] = $field['widget_module']; + } + + unset($field['widget_type']); + unset($field['weight']); + unset($field['label']); + unset($field['description']); + unset($field['widget_module']); + unset($field['widget_settings']); + + // If content.module is handling the default value, + // initialize $widget_settings with default values, + if (isset($field['default_value']) && isset($field['default_value_php']) && + content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) { + $field['widget']['default_value'] = !empty($field['default_value']) ? $field['default_value'] : NULL; + $field['widget']['default_value_php'] = !empty($field['default_value_php']) ? $field['default_value_php'] : NULL; + unset($field['default_value']); + unset($field['default_value_php']); + } + return $field; +} + +/** + * Collapse field info from field => widget to flattened form values. + */ +function content_field_instance_collapse($field) { + if (!isset($field['widget'])) { + return $field; + } + $field['widget_settings'] = !empty($field['widget']) ? $field['widget'] : array(); + $field['widget_type'] = !empty($field['widget']['type']) ? $field['widget']['type'] : ''; + $field['weight'] = !empty($field['widget']['weight']) ? $field['widget']['weight'] : 0; + $field['label'] = !empty($field['widget']['label']) ? $field['widget']['label'] : $field['field_name']; + $field['description'] = !empty($field['widget']['description']) ? $field['widget']['description'] : ''; + $field['type_name'] = !empty($field['type_name']) ? $field['type_name'] : ''; + + if (!empty($field['widget']['module'])) { + $widget_module = $field['widget']['module']; + } + elseif (!empty($field['widget']['type'])) { + $widget_types = _content_widget_types(); + $widget_module = $widget_types[$field['widget']['type']]['module']; + } + else { + $widget_module = ''; + } + $field['widget_module'] = $widget_module; + unset($field['widget_settings']['type']); + unset($field['widget_settings']['weight']); + unset($field['widget_settings']['label']); + unset($field['widget_settings']['description']); + unset($field['widget_settings']['module']); + unset($field['widget']); + return $field; +} + +/** + * Create a new field instance. + * + * @param $field + * An array of properties to create the field with, input either in + * the field => widget format used by the content module or as an + * array of form values. + * + * Required values: + * - field_name, the name of the field to be created + * - type_name, the content type of the instance to be created + * + * If there is no prior instance to create this from, we also need: + * - type, the type of field to create + * - widget_type, the type of widget to use + * @param $rebuild + * TRUE to clear content type caches and rebuild menu (default). + * FALSE allows the caller to process several fields at a time quickly, but then + * the caller is reponsible to clear content type caches and rebuild menu as soon + * as all fields have been processed. For example: + * @code + * // Create several fields at a time. + * foreach ($fields as $field) { + * content_field_instance_create($field, FALSE); + * } + * // Clear caches and rebuild menu. + * content_clear_type_cache(TRUE); + * menu_rebuild(); + * @endcode + * @see content_clear_type_cache() + * @see menu_rebuild() + */ +function content_field_instance_create($field, $rebuild = TRUE) { + include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc'); + + $form_values = $field; + $field = content_field_instance_expand($field); + + // If there are prior instances, fill out missing values from the prior values, + // otherwise get missing values from default values. + $prior_instances = content_field_instance_read(array('field_name' => $field['field_name'])); + if (!empty($prior_instances) && is_array($prior_instances)) { + $prev_field = content_field_instance_expand($prior_instances[0]); + + // Weight, label, and description may have been forced into the $field + // by content_field_instance_expand(). If there is a previous instance to + // get these values from and there was no value supplied originally, use + // the previous value. + $field['widget']['weight'] = isset($form_values['weight']) ? $form_values['weight'] : $prev_field['widget']['weight']; + $field['widget']['label'] = isset($form_values['label']) ? $form_values['label'] : $prev_field['widget']['label']; + $field['widget']['description'] = isset($form_values['description']) ? $form_values['description'] : $prev_field['widget']['description']; + } + else { + $prev_field = array('widget' => array()); + } + + // If we have a field type, we can build default values for this field type. + $default_values = array('widget' => array()); + if (isset($field['type'])) { + $default_values = content_field_default_values($field['type']); + $default_instance_values = content_instance_default_values($field['field_name'], $field['type_name'], $field['widget']['type']); + $default_values = content_field_instance_expand(array_merge($default_values, $default_instance_values)); + } + + // Merge default values, previous values, and current values to create + // a complete field array. + $widget = array_merge($default_values['widget'], $prev_field['widget'], $field['widget']); + $field = array_merge($default_values, $prev_field, $field); + $field['widget'] = $widget; + + // Make sure we know what module to invoke for field info. + if (empty($field['module']) && !empty($field['type'])) { + $field_types = _content_field_types(); + $field['module'] = $field_types[$field['type']]['module']; + } + + // The storage type may need to be updated. + $field['db_storage'] = content_storage_type($field); + + // Get a fresh copy of the column information whenever a field is created. + $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field); + + if (empty($prev_field['widget']) || $prior_instances < 1) { + // If this is the first instance, create the field. + $field['db_storage'] = $field['multiple'] > 0 ? CONTENT_DB_STORAGE_PER_FIELD : CONTENT_DB_STORAGE_PER_CONTENT_TYPE; + _content_field_write($field, 'create'); + } + elseif (!empty($prev_field['widget']) && $prev_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && count($prior_instances) > 0) { + // If the database storage has changed, update the field and previous instances. + $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD; + + foreach ($prior_instances as $instance) { + $new_instance = $instance; + $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD; + + // Invoke hook_content_fieldapi(). + module_invoke_all('content_fieldapi', 'update instance', $new_instance); + + content_alter_schema($instance, $new_instance); + } + } + + // Invoke hook_content_fieldapi(). + module_invoke_all('content_fieldapi', 'create instance', $field); + + // Update the field and the instance with the latest values. + _content_field_write($field, 'update'); + _content_field_instance_write($field, 'create'); + + content_alter_schema(array(), $field); + + if ($rebuild) { + content_clear_type_cache(TRUE); + menu_rebuild(); + } + + return $field; +} + +/** + * Update an existing field instance. + * + * @param $field + * An array of properties to update the field with, input either in + * the field => widget format used by the content module or as an + * array of form values. + * @param $rebuild + * TRUE to clear content type caches and rebuild menu (default). + * FALSE allows the caller to process several fields at a time quickly, but then + * the caller is reponsible to clear content type caches and rebuild menu as soon + * as all fields have been processed. For example: + * @code + * // Update several fields at a time. + * foreach ($fields as $field) { + * content_field_instance_update($field, FALSE); + * } + * // Clear caches and rebuild menu. + * content_clear_type_cache(TRUE); + * menu_rebuild(); + * @endcode + * @see content_clear_type_cache() + * @see menu_rebuild() + */ +function content_field_instance_update($field, $rebuild = TRUE) { + include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc'); + + // Ensure the field description is in the 'expanded' form. + $field = content_field_instance_expand($field); + + // Get the previous value from the table. + $previous = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $field['type_name'])); + $prev_field = array_pop($previous); + + // Create a complete field array by merging the previous and current values, + // letting the current values overwrite the previous ones. + $widget = array_merge($prev_field['widget'], $field['widget']); + $field = array_merge($prev_field, $field); + $field['widget'] = $widget; + + // Make sure we know what module to invoke for field info. + if (empty($field['module']) && !empty($field['type'])) { + $field_types = _content_field_types(); + $field['module'] = $field_types[$field['type']]['module']; + } + + // The storage type may need to be updated. + $field['db_storage'] = content_storage_type($field); + + // Changes in field values may affect columns, or column + // information may have changed, get a fresh copy. + $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field); + + // If the database storage has changed, update the field and previous instances. + $prior_instances = content_field_instance_read(array('field_name' => $field['field_name'])); + + if ($prev_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && count($prior_instances) > 1) { + // Update the field's data storage. + $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD; + + // Update the schema for prior instances to adapt to the change in db storage. + foreach ($prior_instances as $instance) { + if ($instance['type_name'] != $field['type_name']) { + $new_instance = $instance; + $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD; + + // Invoke hook_content_fieldapi(). + module_invoke_all('content_fieldapi', 'update instance', $new_instance); + + content_alter_schema($instance, $new_instance); + } + } + } + + // Invoke hook_content_fieldapi(). + module_invoke_all('content_fieldapi', 'update instance', $field); + + // Update the field and the instance with the latest values. + _content_field_write($field, 'update'); + _content_field_instance_write($field, 'update'); + + content_alter_schema($prev_field, $field); + + if ($rebuild) { + content_clear_type_cache(TRUE); + + // The label is in the menu tree, so we need a menu rebuild + // if the label changes. + if ($prev_field['widget']['label'] != $field['widget']['label']) { + menu_rebuild(); + } + } + + return $field; +} + +/** + * Write a field record. + * + * @param $field + * The field array to process. + */ +function _content_field_write($field, $op = 'update') { + // Rearrange the data to create the global_settings array. + $field['global_settings'] = array(); + $setting_names = (array) module_invoke($field['module'], 'field_settings', 'save', $field); + drupal_alter('field_settings', $setting_names, 'save', $field); + + foreach ($setting_names as $setting) { + // Unlike _content_field_instance_write() and 'widget_settings', 'global_settings' + // is never preexisting, so we take no particular precautions here. + $field['global_settings'][$setting] = isset($field[$setting]) ? $field[$setting] : ''; + unset($field[$setting]); + } + // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'. + $field['db_columns'] = $field['columns']; + + switch ($op) { + case 'create': + drupal_write_record(content_field_tablename(), $field); + break; + case 'update': + drupal_write_record(content_field_tablename(), $field, 'field_name'); + break; + } + unset($field['db_columns']); + return $field; +} + +/** + * Write a field instance record. + * + * @param $field + * The field array to process. + */ +function _content_field_instance_write($field, $op = 'update') { + // Collapse the field => widget format, so that the values to be saved by + // drupal_write_record are on top-level. + $field = content_field_instance_collapse($field); + + // Rearrange the data to create the widget_settings array. + $setting_names = (array) module_invoke($field['widget_module'], 'widget_settings', 'save', $field); + drupal_alter('widget_settings', $setting_names, 'save', $field); + foreach ($setting_names as $setting) { + // In some cases (when the updated $field was originally read from + // the db, as opposed to gathered from the values of a form), the values + // are already in the right place, we take care to not wipe them. + if (isset($field[$setting])) { + $field['widget_settings'][$setting] = $field[$setting]; + unset($field[$setting]); + } + } + + switch ($op) { + case 'create': + drupal_write_record(content_instance_tablename(), $field); + break; + case 'update': + drupal_write_record(content_instance_tablename(), $field, array('field_name', 'type_name')); + break; + } + return $field; +} + +/** + * Load a field instance. + * + * @param $param + * An array of properties to use in selecting a field instance. Valid keys: + * - 'type_name' - The name of the content type in which the instance exists. + * - 'field_name' - The name of the field whose instance is to be loaded. + * if NULL, all instances will be returned. + * @param $include_inactive + * TRUE will return field instances that are 'inactive', because their field + * module or widget module is currently disabled. + * @return + * The field arrays. + */ +function content_field_instance_read($param = NULL, $include_inactive = FALSE) { + $cond = array(); + $args = array(); + if (is_array($param)) { + // Turn the conditions into a query. + foreach ($param as $key => $value) { + $cond[] = 'nfi.'. db_escape_string($key) ." = '%s'"; + $args[] = $value; + } + } + if (!$include_inactive) { + $cond[] = 'nf.active = 1'; + $cond[] = 'nfi.widget_active = 1'; + } + $where = $cond ? ' WHERE '. implode(' AND ', $cond) : ''; + + $db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ". + " JOIN {". content_field_tablename() ."} nf ON nfi.field_name = nf.field_name ". + "$where ORDER BY nfi.weight ASC, nfi.label ASC", $args); + + $fields = array(); + while ($instance = db_fetch_array($db_result)) { + // Unserialize arrays. + foreach (array('widget_settings', 'display_settings', 'global_settings', 'db_columns') as $key) { + $instance[$key] = (!empty($instance[$key])) ? (array) unserialize($instance[$key]) : array(); + } + // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'. + $instance['columns'] = $instance['db_columns']; + unset($instance['db_columns']); + + // Unfold 'global_settings'. + foreach ($instance['global_settings'] as $key => $value) { + $instance[$key] = $value; + } + unset($instance['global_settings']); + + // Put the field in the $field => 'widget' structure that is used + // all around content.module. + $field = content_field_instance_expand($instance); + + // Invoke hook_content_fieldapi(). + module_invoke_all('content_fieldapi', 'read instance', $field); + $fields[] = $field; + } + return $fields; +} + +/** + * Delete an existing field instance. + * + * @param $field_name + * The field name to delete. + * @param $type_name + * The content type where the field instance is going to be deleted. + * @param $rebuild + * TRUE to clear content type caches and rebuild menu (default). + * FALSE allows the caller to process several fields at a time quickly, but then + * the caller is reponsible to clear content type caches and rebuild menu as soon + * as all fields have been processed. For example: + * @code + * // Delete several fields at a time. + * foreach ($fields as $field) { + * content_field_instance_delete($field['field_name'], $type_name, FALSE); + * } + * // Clear caches and rebuild menu. + * content_clear_type_cache(TRUE); + * menu_rebuild(); + * @endcode + * @see content_clear_type_cache() + * @see menu_rebuild() + */ +function content_field_instance_delete($field_name, $type_name, $rebuild = TRUE) { + include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc'); + + // Get the previous field value. + $field = array_pop(content_field_instance_read(array('field_name' => $field_name, 'type_name' => $type_name))); + + // Invoke hook_content_fieldapi(). + module_invoke_all('content_fieldapi', 'delete instance', $field); + + db_query("DELETE FROM {". content_instance_tablename() . + "} WHERE field_name = '%s' AND type_name = '%s'", $field['field_name'], $field['type_name']); + + // If no instances remain, delete the field entirely. + $instances = content_field_instance_read(array('field_name' => $field_name)); + if (sizeof($instances) < 1) { + db_query("DELETE FROM {". content_field_tablename() ."} WHERE field_name = '%s'", $field['field_name']); + content_alter_schema($field, array()); + } + // If only one instance remains, we may need to change the database + // representation for this field. + elseif (sizeof($instances) == 1 && !($field['multiple'])) { + // Multiple-valued fields are always stored per-field-type. + $instance = $instances[0]; + $new_instance = $instance; + $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE; + _content_field_write($new_instance, 'update'); + + content_alter_schema($instance, $new_instance); + } + + // If the deleted instance was the last field for the content type, + // we drop the per-type table. We also consider possibly inactive fields. + if (!content_field_instance_read(array('type_name' => $field['type_name']), TRUE)) { + $base_tablename = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + if (db_table_exists($base_tablename)) { + db_drop_table($ret, $base_tablename); + } + } + + if ($rebuild) { + content_clear_type_cache(TRUE); + menu_rebuild(); + } + + return $field; +} + +/** + * Delete all data related to a module. + * + * @param string $module + */ +function content_module_delete($module) { + // Delete the field data. + // If content module has been uninstalled first, all tables + // have already been dropped, and running that code will raise errors. + if (db_table_exists(content_instance_tablename())) { + $results = db_query("SELECT field_name, type_name FROM {". content_instance_tablename() ."} WHERE widget_module = '%s'", $module); + while ($field = db_fetch_array($results)) { + content_field_instance_delete($field['field_name'], $field['type_name'], FALSE); + } + // Force the caches and static arrays to update to the new info. + content_clear_type_cache(TRUE); + menu_rebuild(); + } +} + +/** + * Make changes needed when a content type is created. + * + * @param $info + * value supplied by hook_node_type() + * + * node_get_types() is still missing the new type at this point due to + * a static caching bug. We ask it to rebuild its cache so that + * content_clear_type_cache() can do its job properly. + */ +function content_type_create($info) { + node_get_types(NULL, NULL, TRUE); + content_clear_type_cache(TRUE); +} + +/** + * Make changes needed when an existing content type is updated. + * + * @param $info + * value supplied by hook_node_type() + */ +function content_type_update($info) { + if (!empty($info->old_type) && $info->old_type != $info->type) { + // Rename the content type in all fields that use changed content type. + db_query("UPDATE {". content_instance_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type)); + + // Rename the content fields table to match new content type name. + $old_type = content_types($info->old_type); + $old_name = _content_tablename($old_type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + $new_name = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + if (db_table_exists($old_name)) { + $ret = array(); + db_rename_table($ret, $old_name, $new_name); + watchdog('content', 'Content fields table %old_name has been renamed to %new_name and field instances have been updated.', array( + '%old_name' => $old_name, '%new_name' => $new_name)); + } + + // Rename the variable storing weights for non-CCK fields. + if ($extra = variable_get('content_extra_weights_'. $info->old_type, array())) { + variable_set('content_extra_weights_'. $info->type, $extra); + variable_del('content_extra_weights_'. $info->old_type); + } + } + + // Reset all content type info. + // Menu needs to be rebuilt as well, but node types need to be rebuilt first. + // node_type_form_submit() takes care of this. + content_clear_type_cache(TRUE); +} + +/** + * Make changes needed when a content type is deleted. + * + * @param $info + * value supplied by hook_node_type() + * + * TODO should we skip doing this entirely since core leaves the + * nodes in the database as orphans and wait until the nodes are + * deleted to respond? + * + */ +function content_type_delete($info) { + // Don't delete data for content-types defined by disabled modules. + if (!empty($info->disabled)) { + return; + } + + // TODO : What about inactive fields ? + // Currently, content_field_instance_delete doesn't work on those... + $fields = content_field_instance_read(array('type_name' => $info->type)); + foreach ($fields as $field) { + content_field_instance_delete($field['field_name'], $info->type, FALSE); + } + $table = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE); + if (db_table_exists($table)) { + $ret = array(); + db_drop_table($ret, $table); + watchdog('content', 'The content fields table %name has been deleted.', array('%name' => $table)); + } + // Menu needs to be rebuilt as well, but node types need to be rebuilt first. + // node_type_form_submit() takes care of this. + content_clear_type_cache(TRUE); +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.devel.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.devel.inc new file mode 100644 index 0000000000000000000000000000000000000000..985813a80302ebe608cea56d96d6dae8ce68baaf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.devel.inc @@ -0,0 +1,218 @@ +<?php +// $Id$ + +/** + * @file + * Functions needed for Devel module integration. + * + * TODO + * This is not really working correctly yet. It is getting called once + * for every field and then generating every field each time. But if + * you only process one field at a time the earlier ones lose their values. + * The current method works to create values, but is overly processor- + * intensive and needs to be reworked in a way that each field is + * only processed once and all values are retained. + */ + +/** + * Enrich the $node that is about to be saved with arbitrary + * information in each of its CCK fields. + **/ +function content_generate_fields(&$node, $field) { + $type_name = $node->type; + $type = content_types($type_name); + $field_types = _content_field_types(); + + if (!empty($type['fields'])) { + foreach ($type['fields'] as $field) { + $node_field = array(); + // If module handles own multiples, then only call its hook once. + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) { + $max = 0; + } + else { + switch ($field['multiple']) { + case 0: + $max = 0; + break; + case 1: + $max = rand(0, 3); //just an arbitrary number for 'unlimited' + break; + default: + $max = $field['multiple']; + break; + } + } + for ($i = 0; $i <= $max; $i++) { + $module = $field_types[$field['type']]['module']; + $function = $module .'_content_generate'; + if (function_exists($function)) { + $result = $function($node, $field); // $items, $teaser, $page + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) { + // Fields that handle their own multiples will add their own deltas. + $node_field = $result; + } + else { + // When multiples are handled by the content module, add a delta for each result. + $node_field[$i] = $result; + } + } + } + $node->{$field['field_name']} = $node_field; + } + } +} + +/** + * A simple function to return multiple values for fields that use + * custom multiple value widgets but don't need any other special multiple + * values handling. This will call the field generation function + * a random number of times and compile the results into a node array. + */ +function content_devel_multiple($function, $node, $field) { + $node_field = array(); + if (function_exists($function)) { + switch ($field['multiple']) { + case 0: + $max = 0; + break; + case 1: + $max = rand(0, 3); //just an arbitrary number for 'unlimited' + break; + default: + $max = $field['multiple']; + break; + } + for ($i = 0; $i <= $max; $i++) { + $node_field[$i] = $function($node, $field); + } + } + return $node_field; +} + +if (module_exists('text')) { + function text_content_generate($node, $field) { + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) { + return content_devel_multiple('_text_content_generate', $node, $field); + } + else { + return _text_content_generate($node, $field); + } + } + + function _text_content_generate($node, $field) { + $node_field = array(); + if ($field['widget']['type'] == 'text_textarea') { + $format = $field['text_processing'] ? rand(0, 3) : 0; + $node_field['value'] = devel_create_content($format); + $node_field['format'] = $format; + } + else { + $allowed_values = content_allowed_values($field); + if (!empty($allowed_values)) { + // Just pick one of the specified allowed values. + $node_field['value'] = array_rand($allowed_values); + } + else { + // Generate a value that respects max_length. + if (empty($field['max_length'])) { + $field['max_length'] = 12; + } + $node_field['value'] = user_password($field['max_length']); + } + } + return $node_field; + } +} + +if (module_exists('number')) { + function number_content_generate($node, $field) { + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) { + return content_devel_multiple('_number_content_generate', $node, $field); + } + else { + return _number_content_generate($node, $field); + } + } + + function _number_content_generate($node, $field) { + $node_field = array(); + $allowed_values = content_allowed_values($field); + if (!empty($allowed_values)) { + // Just pick one of the specified allowed values. + $node_field['value'] = array_rand($allowed_values); + } + else { + $min = is_numeric($field['min']) ? $field['min'] : 0; + switch ($field['type']) { + case 'number_integer': + $max = is_numeric($field['max']) ? $field['max'] : 10000; + $decimal = 0; + $scale = 0; + break; + + case 'number_decimal': + $precision = is_numeric($field['precision']) ? $field['precision'] : 10; + $scale = is_numeric($field['scale']) ? $field['scale'] : 2; + $max = is_numeric($field['max']) ? $field['max'] : pow(10, ($precision - $scale)); + $decimal = rand(0, (10 * $scale)) / 100; + break; + + case 'number_float': + $precision = rand(10, 32); + $scale = rand(0, 2); + $decimal = rand(0, (10 * $scale)) / 100; + $max = is_numeric($field['max']) ? $field['max'] : pow(10, ($precision - $scale)); + break; + } + $node_field['value'] = round((rand($min, $max) + $decimal), $scale); + } + return $node_field; + } +} + +if (module_exists('nodereference')) { + function nodereference_content_generate($node, $field) { + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) { + return content_devel_multiple('_nodereference_content_generate', $node, $field); + } + else { + return _nodereference_content_generate($node, $field); + } + } + + function _nodereference_content_generate($node, $field) { + $node_field = array(); + $allowed_values = nodereference_allowed_values($field); + unset($allowed_values[0]); + if (!empty($allowed_values)) { + // Just pick one of the specified allowed values. + $node_field['nid'] = array_rand($allowed_values); + } + return $node_field; + } +} + +if (module_exists('userreference')) { + function userreference_content_generate($node, $field) { + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) { + return content_devel_multiple('_userreference_content_generate', $node, $field); + } + else { + return _userreference_content_generate($node, $field); + } + } + + function _userreference_content_generate($node, $field) { + $node_field = array(); + $allowed_values = userreference_allowed_values($field); + if (isset($allowed_values['none'])) { + unset($allowed_values['none']); + } + if (!empty($allowed_values)) { + // Just pick one of the specified allowed values. + $node_field['uid'] = array_rand($allowed_values); + } + return $node_field; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.diff.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.diff.inc new file mode 100644 index 0000000000000000000000000000000000000000..42a3634da86d811899b824b6c175e479f91a8059 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.diff.inc @@ -0,0 +1,128 @@ +<?php +// $Id$ + +/** + * @file hook_diff() implementations for CCK (especially fields). + * + * These should use a field-hook so the data for the diff is + * field-type specific. + */ + +/** + * Implementation of hook_diff() + */ +function content_diff($old_node, $new_node) { + $result = array(); + // Prevent against invalid 'nodes' built by broken 3rd party code. + if (isset($new_node->type)) { + $type = content_types($new_node->type); + $field_types = _content_field_types(); + foreach ($type['fields'] as $field) { + // Ignore fields the current user is not allowed to view. + if (!content_access('view', $field, NULL, $new_node)) { + continue; + } + $function = $field_types[$field['type']]['module'] . '_content_diff_values'; + $function = function_exists($function) ? $function : 'content_content_diff_values'; + $old_values = array(); + $new_values = array(); + if (isset($old_node->$field['field_name'])) { + $old_values = $function($old_node, $field, $old_node->$field['field_name']); + } + if (isset($new_node->$field['field_name'])) { + $new_values = $function($new_node, $field, $new_node->$field['field_name']); + } + if ($old_values || $new_values) { + $result[$field['field_name']] = array( + '#name' => $field['widget']['label'], + '#old' => $old_values, + '#new' => $new_values, + '#weight' => $field['widget']['weight'], + '#format' => array( + 'show_header' => FALSE, + ), + ); + } + } + } + return $result; +} + +/** + * Default 'implementation' of hook_content_diff_values. + * + * Note that diff.module takes care of running check_plain on the output. + */ +function content_content_diff_values($node, $field, $items) { + $return = array(); + foreach ($items as $item) { + foreach (explode("\n", $item['value']) as $i) { + $return[] = $i; + } + } + return $return; +} + +if (module_exists('userreference')) { + /** + * Implementation of hook_content_diff_values. + */ + function userreference_content_diff_values($node, $field, $items) { + static $titles = array(); + // Gather ids. + $ids = array(); + foreach ($items as $item) { + if ($item['uid'] && is_numeric($item['uid'])) { + $ids[] = $item['uid']; + } + } + // Fetch titles we don't know yet. + $queried_ids = array_diff($ids, array_keys($titles)); + if ($queried_ids) { + $result = db_query('SELECT uid, name FROM {users} WHERE uid IN ('. db_placeholders($queried_ids) .')', $queried_ids); + while ($row = db_fetch_array($result)) { + $titles[$row['uid']] = $row['name']; + } + } + // Return result. + $return = array(); + foreach ($items as $item) { + if ($item['uid'] && isset($titles[$item['uid']])) { + $return[] = $titles[$item['uid']]; + } + } + return $return; + } +} + +if (module_exists('nodereference')) { + /** + * Implementation of hook_content_diff_values. + */ + function nodereference_content_diff_values($node, $field, $items) { + static $titles = array(); + // Gather ids. + $ids = array(); + foreach ($items as $item) { + if ($item['nid'] && is_numeric($item['nid'])) { + $ids[] = $item['nid']; + } + } + // Fetch titles we don't know yet. + $queried_ids = array_diff($ids, array_keys($titles)); + if ($queried_ids) { + $result = db_query('SELECT nid, title FROM {node} WHERE nid IN ('. db_placeholders($queried_ids) .')', $queried_ids); + while ($row = db_fetch_array($result)) { + $titles[$row['nid']] = $row['title']; + } + } + // Return result. + $return = array(); + foreach ($items as $item) { + if ($item['nid'] && isset($titles[$item['nid']])) { + $return[] = $titles[$item['nid']]; + } + } + return $return; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.node_form.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.node_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..681a3401cbc5ccab1ccc8ec5c3f67308badc525c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.node_form.inc @@ -0,0 +1,380 @@ +<?php +// $Id$ + +/** + * @file + * Create fields' form for a content type. + * + * Each field defines its own component of the content entry form, via its + * chosen widget. + */ +function content_form(&$form, &$form_state) { + $type = content_types($form['type']['#value']); + foreach ($type['fields'] as $field_name => $field) { + $form['#field_info'][$field['field_name']] = $field; + $form += (array) content_field_form($form, $form_state, $field); + } + return $form; +} + +/** + * Create a separate form element for each field. + * + * // TODO: $count param ? not used anymore ? + * Hook_widget() picks up two new values, $count and $delta, to help + * widgets know what information to return since multiple values are + * sometimes controlled by the content module. + * + * @param $form + * the form to add this field element to + * @param $form_state + * the form_state for the above form + * @param $field + * the field array to use to create the form element + * @param $get_delta + * use to get only a specific delta value of a multiple value field, otherwise + * function will return the entire $field form element. + */ +function content_field_form(&$form, &$form_state, $field, $get_delta = NULL) { + $form['#cache'] = FALSE; + $node = $form['#node']; + $addition = array(); + $form_element = array(); + $field_name = $field['field_name']; + + $items = array(); + + // TODO: is the "if (function_exists($function)) {" needed ? + // defining the $function here makes it unclear where it is actually called + $function = $field['widget']['module'] .'_widget'; + if (function_exists($function)) { + // Prepare the values to be filled in the widget. + // We look in the following places: + // - Form submitted values + // - Node values (when editing an existing node), or pre-filled values (when + // creating a new node translation) + // - Default values set for the field (when creating a new node). + if (!empty($form_state['values'][$field['field_name']])) { + $items = $form_state['values'][$field['field_name']]; + // If there was an AHAH add more button in this field, don't save it. + unset($items[$field['field_name'] .'_add_more']); + } + elseif (!empty($node->$field['field_name'])) { + $items = $node->$field['field_name']; + } + elseif (empty($node->nid)) { + if (content_callback('widget', 'default value', $field) != CONTENT_CALLBACK_NONE) { + // If a module wants to insert custom default values here, + // it should provide a hook_default_value() function to call, + // otherwise the content module's content_default_value() function + // will be used. + $callback = content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_CUSTOM ? $field['widget']['module'] .'_default_value' : 'content_default_value'; + if (function_exists($callback)) { + $items = $callback($form, $form_state, $field, 0); + } + } + } + + // See if access to this form element is restricted, + // if so, skip widget processing and just set the value. + $access = content_access('edit', $field, NULL, $node); + if (!$access) { + $addition[$field_name] = array( + '#access' => $access, + '#type' => 'value', + '#value' => $items, + ); + return $addition; + } + + // If content module handles multiple values for this form element, + // and not selecting an individual $delta, process the multiple value form. + if (!isset($get_delta) && content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) { + $form_element = content_multiple_value_form($form, $form_state, $field, $items); + } + // If the widget is handling multiple values (e.g optionwidgets), + // or selecting an individual element, just get a single form + // element and make it the $delta value. + else { + $delta = isset($get_delta) ? $get_delta : 0; + if ($element = $function($form, $form_state, $field, $items, $delta)) { + $title = check_plain(t($field['widget']['label'])); + $description = content_filter_xss(t($field['widget']['description'])); + $defaults = array( + '#required' => $get_delta > 0 ? FALSE : $field['required'], + '#columns' => array_keys($field['columns']), + '#title' => $title, + '#description' => $description, + '#delta' => $delta, + '#field_name' => $field['field_name'], + '#type_name' => $field['type_name'], + ); + // If we're processing a specific delta value for a field where the + // content module handles multiples, set the delta in the result. + // For fields that handle their own processing, we can't make assumptions + // about how the field is structured, just merge in the returned value. + if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) { + $form_element[$delta] = array_merge($element, $defaults); + } + else { + $form_element = array_merge($element, $defaults); + } + } + } + + // Field name is needed at top level as well as the individual elements + // so the multiple values or other field level theme or processing can find it. + if ($form_element) { + $defaults = array( + '#field_name' => $field['field_name'], + '#tree' => TRUE, + '#weight' => $field['widget']['weight'], + '#access' => $access, + // TODO: what's the need for #count ? does not seem to be used anywhere ? + '#count' => count($form_element), + ); + $addition[$field['field_name']] = array_merge($form_element, $defaults); + } + } + return $addition; +} + +/** + * Special handling to create form elements for multiple values. + * + * Handles generic features for multiple fields: + * - number of widgets + * - AHAH-'add more' button + * - drag-n-drop value reordering + */ +function content_multiple_value_form(&$form, &$form_state, $field, $items) { + $field_name = $field['field_name']; + + switch ($field['multiple']) { + case 0: + $max = 0; + break; + case 1: + $filled_items = content_set_empty($field, $items); + $current_item_count = isset($form_state['item_count'][$field_name]) + ? $form_state['item_count'][$field_name] + : count($items); + // We always want at least one empty icon for the user to fill in. + $max = ($current_item_count > count($filled_items)) + ? $current_item_count - 1 + : $current_item_count; + + break; + default: + $max = $field['multiple'] - 1; + break; + } + + $title = check_plain(t($field['widget']['label'])); + $description = content_filter_xss(t($field['widget']['description'])); + + $form_element = array( + '#theme' => 'content_multiple_values', + '#title' => $title, + '#required' => $field['required'], + '#description' => $description, + ); + $function = $field['widget']['module'] .'_widget'; + + for ($delta = 0; $delta <= $max; $delta++) { + if ($element = $function($form, $form_state, $field, $items, $delta)) { + $defaults = array( + '#title' => ($field['multiple'] >= 1) ? '' : $title, + '#description' => ($field['multiple'] >= 1) ? '' : $description, + '#required' => $delta == 0 && $field['required'], + '#weight' => $delta, + '#delta' => $delta, + '#columns' => array_keys($field['columns']), + '#field_name' => $field_name, + '#type_name' => $field['type_name'], + ); + + // Add an input field for the delta (drag-n-drop reordering), which will + // be hidden by tabledrag js behavior. + if ($field['multiple'] >= 1) { + // We name the element '_weight' to avoid clashing with column names + // defined by field modules. + $element['_weight'] = array( + '#type' => 'weight', + '#delta' => $max, // this 'delta' is the 'weight' element's property + '#default_value' => isset($items[$delta]['_weight']) ? $items[$delta]['_weight'] : $delta, + '#weight' => 100, + ); + } + + $form_element[$delta] = array_merge($element, $defaults); + } + } + + // Add AHAH add more button, if not working with a programmed form. + if ($field['multiple'] == 1 && empty($form['#programmed'])) { + // Make sure the form is cached so ahah can work. + $form['#cache'] = TRUE; + $content_type = content_types($field['type_name']); + $field_name_css = str_replace('_', '-', $field_name); + + $form_element[$field_name .'_add_more'] = array( + '#type' => 'submit', + '#name' => $field_name .'_add_more', + '#value' => t('Add another item'), + '#weight' => $field['widget']['weight'] + $max + 1, + // Submit callback for disabled JavaScript. drupal_get_form() might get + // the form from the cache, so we can't rely on content_form_alter() + // including this file. Therefore, call a proxy function to do this. + '#submit' => array('content_add_more_submit_proxy'), + '#ahah' => array( + 'path' => 'content/js_add_more/'. $content_type['url_str'] .'/'. $field_name, + 'wrapper' => $field_name_css .'-items', + 'method' => 'replace', + 'effect' => 'fade', + ), + // When JS is disabled, the content_add_more_submit handler will find + // the relevant field using these entries. + '#field_name' => $field_name, + '#type_name' => $field['type_name'], + ); + + // Add wrappers for the fields and 'more' button. + $form_element['#prefix'] = '<div id="'. $field_name_css .'-items">'; + $form_element['#suffix'] = '</div>'; + $form_element[$field_name .'_add_more']['#prefix'] = '<div class="content-add-more clear-block">'; + $form_element[$field_name .'_add_more']['#suffix'] = '</div>'; + } + return $form_element; +} + +/** + * Submit handler to add more choices to a content form. This handler is used when + * JavaScript is not available. It makes changes to the form state and the + * entire form is rebuilt during the page reload. + */ +function content_add_more_submit($form, &$form_state) { + // Set the form to rebuild and run submit handlers. + node_form_submit_build_node($form, $form_state); + $field_name = $form_state['clicked_button']['#field_name']; + $type_name = $form_state['clicked_button']['#type_name']; + + // Make the changes we want to the form state. + if ($form_state['values'][$field_name][$field_name .'_add_more']) { + $form_state['item_count'][$field_name] = count($form_state['values'][$field_name]); + } +} + +/** + * Menu callback for AHAH addition of new empty widgets. + */ +function content_add_more_js($type_name_url, $field_name) { + $type = content_types($type_name_url); + $field = content_fields($field_name, $type['type']); + + if (($field['multiple'] != 1) || empty($_POST['form_build_id'])) { + // Invalid request. + drupal_json(array('data' => '')); + exit; + } + + // Retrieve the cached form. + $form_state = array('submitted' => FALSE); + $form_build_id = $_POST['form_build_id']; + $form = form_get_cache($form_build_id, $form_state); + if (!$form) { + // Invalid form_build_id. + drupal_json(array('data' => '')); + exit; + } + + // We don't simply return a new empty widget to append to existing ones, because + // - ahah.js won't simply let us add a new row to a table + // - attaching the 'draggable' behavior won't be easy + // So we resort to rebuilding the whole table of widgets including the existing ones, + // which makes us jump through a few hoops. + + // The form that we get from the cache is unbuilt. We need to build it so that + // _value callbacks can be executed and $form_state['values'] populated. + // We only want to affect $form_state['values'], not the $form itself + // (built forms aren't supposed to enter the cache) nor the rest of $form_data, + // so we use copies of $form and $form_data. + $form_copy = $form; + $form_state_copy = $form_state; + $form_copy['#post'] = array(); + form_builder($_POST['form_id'], $form_copy, $form_state_copy); + // Just grab the data we need. + $form_state['values'] = $form_state_copy['values']; + // Reset cached ids, so that they don't affect the actual form we output. + form_clean_id(NULL, TRUE); + + // Sort the $form_state['values'] we just built *and* the incoming $_POST data + // according to d-n-d reordering. + unset($form_state['values'][$field_name][$field['field_name'] .'_add_more']); + foreach ($_POST[$field_name] as $delta => $item) { + $form_state['values'][$field_name][$delta]['_weight'] = $item['_weight']; + } + $form_state['values'][$field_name] = _content_sort_items($field, $form_state['values'][$field_name]); + $_POST[$field_name] = _content_sort_items($field, $_POST[$field_name]); + + // Build our new form element for the whole field, asking for one more element. + $form_state['item_count'] = array($field_name => count($_POST[$field_name]) + 1); + $form_element = content_field_form($form, $form_state, $field); + // Let other modules alter it. + // We pass an empty array as hook_form_alter's usual 'form_state' parameter, + // instead of $form_state (for reasons we may never remember). + // However, this argument is still expected to be passed by-reference + // (and PHP5.3 will throw an error if it isn't.) This leads to: + $data = &$form_element; + $empty_form_state = array(); + $data['__drupal_alter_by_ref'] = array(&$empty_form_state); + drupal_alter('form', $data, 'content_add_more_js'); + + // Add the new element at the right place in the (original, unbuilt) form. + if (module_exists('fieldgroup') && ($group_name = _fieldgroup_field_get_group($type['type'], $field_name))) { + $form[$group_name][$field_name] = $form_element[$field_name]; + } + else { + $form[$field_name] = $form_element[$field_name]; + } + + // Save the new definition of the form. + $form_state['values'] = array(); + form_set_cache($form_build_id, $form, $form_state); + + // Build the new form against the incoming $_POST values so that we can + // render the new element. + $delta = max(array_keys($_POST[$field_name])) + 1; + $_POST[$field_name][$delta]['_weight'] = $delta; + $form_state = array('submitted' => FALSE); + $form += array( + '#post' => $_POST, + '#programmed' => FALSE, + ); + $form = form_builder($_POST['form_id'], $form, $form_state); + + // Render the new output. + $field_form = (!empty($group_name)) ? $form[$group_name][$field_name] : $form[$field_name]; + // We add a div around the new content to receive the ahah effect. + $field_form[$delta]['#prefix'] = '<div class="ahah-new-content">'. (isset($field_form[$delta]['#prefix']) ? $field_form[$delta]['#prefix'] : ''); + $field_form[$delta]['#suffix'] = (isset($field_form[$delta]['#suffix']) ? $field_form[$delta]['#suffix'] : '') .'</div>'; + // Prevent duplicate wrapper. + unset($field_form['#prefix'], $field_form['#suffix']); + + // If a newly inserted widget contains AHAH behaviors, they normally won't + // work because AHAH doesn't know about those - it just attaches to the exact + // form elements that were initially specified in the Drupal.settings object. + // The new ones didn't exist then, so we need to update Drupal.settings + // by ourselves in order to let AHAH know about those new form elements. + $javascript = drupal_add_js(NULL, NULL); + $output_js = isset($javascript['setting']) ? '<script type="text/javascript">jQuery.extend(Drupal.settings, '. drupal_to_js(call_user_func_array('array_merge_recursive', $javascript['setting'])) .');</script>' : ''; + + $output = theme('status_messages') . drupal_render($field_form) . $output_js; + + // Using drupal_json() breaks filefield's file upload, because the jQuery + // Form plugin handles file uploads in a way that is not compatible with + // 'text/javascript' response type. + $GLOBALS['devel_shutdown'] = FALSE; + print drupal_to_js(array('status' => TRUE, 'data' => $output)); + exit; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.rules.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.rules.inc new file mode 100644 index 0000000000000000000000000000000000000000..9ebcb87f4e0c37e94f443cbb3decd1563a868b29 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.rules.inc @@ -0,0 +1,348 @@ +<?php +// $Id$ + +/** + * @file + * Provides basic rules module support. + */ + +/** + * Implementation of hook_rules_action_info(). + */ +function content_rules_action_info() { + $info = array(); + $info['content_rules_action_populate_field'] = array( + 'label' => t('Populate a field'), + 'arguments' => array( + 'node' => array( + 'type' => 'node', + 'label' => t('Content'), + ), + ), + 'eval input' => array('code'), + 'help' => t('You should make sure that the used field exists in the given content type.'), + 'module' => 'CCK', + ); + return $info; +} + +/** + * Action: populate a field. + */ +function content_rules_action_populate_field($node, $settings, $element, &$state) { + // Get information about the field. + $field = content_fields($settings['field_name'], $node->type); + $value = _content_rules_get_field_value($settings, $state); + + if (!empty($field) && is_array($value)) { + $node->$settings['field_name'] = $value; + return array('node' => $node); + } +} + + +/** + * Action "populate a field" configuration form. + * This is a multistep form! + */ +function content_rules_action_populate_field_form($settings, &$form, &$form_state) { + $settings += array('field_name' => '', 'code' => '', 'value' => NULL); + if (empty($settings['field_name'])) { + $form['settings']['field_name'] = array( + '#type' => 'select', + '#title' => t('Field'), + '#options' => content_rules_get_field_names_by_type(), + '#default_value' => $settings['field_name'], + '#description' => t('Select the machine-name of the field.'), + '#required' => TRUE, + ); + // Hide some form elements in the first step. + $form['negate']['#access'] = FALSE; + $form['input_help']['#access'] = FALSE; + $form['weight']['#access'] = FALSE; + + // Replace the usual submit handlers with a own handler. + $form['submit']['#submit'] = array('content_rules_action_populate_field_form_step_submit'); + $form['submit']['#value'] = t('Continue'); + } + else { + // Show the fields form here. + module_load_include('inc', 'content', 'includes/content.node_form'); + $field = content_fields($settings['field_name']); + + $form['#node'] = (object)array('type' => '', $settings['field_name'] => $settings['value']); + $form['#field_info'][$field['field_name']] = $field; + // We can't put it into $form['settings'] as this would break AHAH callbacks + $form += (array) content_field_form($form, $form_state, $field); + $form[ $settings['field_name'] ]['#weight'] = 4; + + unset($form['#cache']); + + // Advanced: PHP code. + $form['advanced_options'] = array( + '#type' => 'fieldset', + '#title' => t('Advanced: Specify the fields value with PHP code'), + '#collapsible' => TRUE, + '#collapsed' => empty($settings['code']), + '#weight' => 5, + ); + + $db_info = content_database_info($field); + $columns = array_keys($db_info['columns']); + foreach ($columns as $key => $column) { + $columns[$key] = t("'@column' => value for @column", array('@column' => $column)); + } + $sample = t("return array(\n 0 => array(@columns),\n // You'll usually want to stop here. Provide more values\n // if you want your 'default value' to be multi-valued:\n 1 => array(@columns),\n 2 => ...\n);", array('@columns' => implode(', ', $columns))); + + $form['advanced_options']['code'] = array( + '#type' => 'textarea', + '#title' => t('Code'), + '#default_value' => $settings['code'], + '#rows' => 6, + '#description' => t('Advanced usage only: PHP code that returns the value to set. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>Using <a href="@link_devel">devel.module\'s</a> \'devel load\' tab on a content page might help you figure out the expected format.', array( + '!sample' => $sample, + '@link_devel' => 'http://www.drupal.org/project/devel', + )), + ); + + // Add this file to be included when the form is built by rules + // as it's needed by CCKs add more button. + // See rules_after_build_include_files(). + $form['#includes'][] = './'. drupal_get_path('module', 'node') .'/node.pages.inc'; + } +} + +function content_rules_action_populate_field_form_step_submit($form, &$form_state) { + $form_state['element']['#settings']['field_name'] = $form_state['values']['settings']['field_name']; +} + +/** + * Validate the chosen value or php code. + */ +function content_rules_action_populate_field_validate($form, &$form_state) { + if (!isset($form_state['element']['#settings']['field_name'])) { + //Just validate the last step. + return; + } + + if (isset($form_state['values']['code']) && ($php = $form_state['values']['code'])) { + if (strpos($php, 'return') === FALSE) { + form_set_error('code', t('You have to return the default value in the expected format.')); + } + } + else { + // Validate the field. + $settings = $form_state['element']['#settings']; + $field = content_fields($settings['field_name']); + $field_types = _content_field_types(); + $function = $field_types[$field['type']]['module'] .'_field'; + if (function_exists($function)) { + $form['#node'] = (object)array('type' => '', $settings['field_name'] => $form_state['values'][$settings['field_name']]); + $items = isset($form['#node']->$field['field_name']) ? $form['#node']->$field['field_name'] : array(); + + //Make sure AHAH 'add more' button isn't sent to the fields + // for processing. + unset($items[$field['field_name'] .'_add_more']); + + $function('validate', $form['#node'], $field, $items, $form, NULL); + content_field('validate', $form['#node'], $field, $items, $form, NULL); + } + } +} + +function content_rules_action_populate_field_submit(&$settings, $form, &$form_state) { + // Take over field values and filter out private properties added by CCK + $settings['value'] = array_filter($form_state['values'][$settings['field_name']], 'is_array'); + + foreach ($settings['value'] as $key => $data) { + foreach (array_filter(array_keys($data)) as $col) { + if ($col[0] == '_') { + unset($settings['value'][$key][$col]); + } + } + if ($key && count(array_filter($settings['value'][$key])) == 0) { + // For multi-valued fields don't check for any additional empty values. + unset($settings['value'][$key]); + } + } + + $settings['code'] = $form_state['values']['code']; + + if (function_exists('rules_action_custom_php_submit')) { + // Support adding variables to the php code, if php module is present. + rules_action_custom_php_submit($settings, $form, $form_state); + } + + // Add all values to the input evaluator, so that textfields / textares can + // make use of it. + $names = array('code'); + + foreach ($settings['value'] as $key => $data) { + foreach (array_filter($data, 'is_string') as $col => $value) { + $names[] = "value|$key|$col"; + } + } + $form_state['element']['#info']['eval input'] = $names; +} + + +/** + * Label callback: Improve the label of the action. + */ +function content_rules_action_populate_field_label($settings, $argument_labels) { + return t("Populate @node's field '@field'", array('@field' => $settings['field_name']) + $argument_labels); +} + +function workflow_ng_action_populate_field_upgrade(&$element) { + $element['#name'] = 'content_rules_action_populate_field'; + $element['#settings']['code'] = $element['#settings']['default_value_php']; + $element['#settings'][$element['#settings']['field_name']] = array(); + unset($element['#settings']['default_value_php']); +} + + +/** + * Implementation of hook_rules_condition_info(). + */ +function content_rules_condition_info() { + $info = array(); + $info['content_rules_field_has_value'] = array( + 'label' => t('Field has value'), + 'arguments' => array( + 'node' => array('type' => 'node', 'label' => t('Content')), + ), + 'eval input' => array('code'), + 'help' => t('You should make sure that the used field exists in the given content type. The condition returns TRUE, if the selected field has the given value.'), + 'module' => 'CCK', + ); + $info['content_rules_field_changed'] = array( + 'label' => t('Field has changed'), + 'arguments' => array( + 'node' => array('type' => 'node', 'label' => t('Content containing changes')), + 'node_unchanged' => array('type' => 'node', 'label' => t('Content not containing changes')), + ), + 'help' => t('You should make sure that the used field exists in the given content type.'), + 'module' => 'CCK', + ); + return $info; +} + +/** + * Condition: Check the value of a field. + */ +function content_rules_field_has_value($node, $settings) { + // Get information about the field. + $field = content_fields($settings['field_name'], $node->type); + $value = _content_rules_get_field_value($settings, $state); + + if (empty($field) || !is_array($value)) { + return FALSE; + } + + return _content_rules_field_has_value($node->$settings['field_name'], $value); +} + +/** + * Use the same configuration form as the "populate field" action. + */ +function content_rules_field_has_value_form($settings, &$form, &$form_state) { + content_rules_action_populate_field_form($settings, $form, $form_state); +} +function content_rules_field_has_value_validate($form, &$form_state) { + content_rules_action_populate_field_validate($form, $form_state); +} +function content_rules_field_has_value_submit(&$settings, $form, &$form_state) { + content_rules_action_populate_field_submit($settings, $form, $form_state); +} + +function content_rules_field_has_value_label($settings, $argument_labels) { + return t("@node's field '@field' has value", array('@field' => $settings['field_name']) + $argument_labels); +} + +/** + * Condition: Check if the field has changed. + */ +function content_rules_field_changed($node1, $node2, $settings) { + // Get information about the field. + $field = content_fields($settings['field_name'], $node1->type); + + return !empty($field) && !_content_rules_field_has_value($node1->$settings['field_name'], $node2->$settings['field_name']); +} + +function content_rules_field_changed_form($settings, &$form, &$form_state) { + $settings += array('field_name' => ''); + $form['settings']['field_name'] = array( + '#type' => 'select', + '#title' => t('Field'), + '#options' => content_rules_get_field_names_by_type(), + '#default_value' => $settings['field_name'], + '#description' => t('Select the machine-name of the field to look at.'), + '#required' => TRUE, + ); +} + +function content_rules_field_changed_label($settings, $argument_labels) { + return t("@node's field '@field' has been changed", array('@field' => $settings['field_name']) + $argument_labels); +} + + +/** + * Returns the fields of a given field type only. + * Suitable for using it with #options. + */ +function content_rules_get_field_names_by_type($type = NULL) { + $fields = array(); + foreach (content_fields() as $field) { + if (!isset($type) || $field['type'] == $type) { + $fields[$field['field_name']] = $field['field_name']; + } + } + asort($fields); + return $fields; +} + +function _content_rules_get_field_value($settings, &$state) { + if ($settings['code']) { + if (function_exists('rules_input_evaluator_php_apply')) { + // Support adding variables to the php code, if php module is present. + $value = rules_input_evaluator_php_apply($settings['code'], $settings['vars'], $state, FALSE); + } + else { + ob_start(); + $value = eval($settings['code']); + ob_end_clean(); + } + } + else { + $value = $settings['value']; + } + return $value; +} + +/** + * Checks whether both field values match in a robust way. + * + * It returns TRUE, only if the number of multiple values matches and + * each property of the cck field's value is the same in the node. + * + * @param $node_value The value present in the node. + * @param $value The value to check for. + */ +function _content_rules_field_has_value($node_value, $value) { + if (count($value) != count($node_value)) { + return FALSE; + } + // Loop over multiple fields + foreach ($value as $delta => $sub_value) { + // Check if all properties of the value are there in the node value too + if (is_array($sub_value) && is_array($node_value[$delta])) { + if (count(array_diff_assoc($sub_value, $node_value[$delta])) != 0) { + return FALSE; + } + } + elseif ($sub_value !== $node_value[$delta]) { + return FALSE; + } + } + return TRUE; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.token.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.token.inc new file mode 100644 index 0000000000000000000000000000000000000000..0ff71b358619273252d21aeb0061cc495f4f3a45 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.token.inc @@ -0,0 +1,187 @@ +<?php +// $Id$ + +/** + * @file + * Implementation of hook_content_build_modes + * (on behalf of token.module) + */ +function token_content_build_modes() { + return array( + 'token' => array( + 'title' => t('Token'), + 'build modes' => array( + 'token' => array( + 'title' => t('Token'), + 'views style' => FALSE, + ), + ), + ), + ); +} + +// Two helper functions that generate appropriate tokens for CCK-added fields. +function content_token_values($type, $object = NULL, $options = array()) { + $tokens = array(); + if ($type == 'node') { + // Prevent against invalid 'nodes' built by broken 3rd party code. + if (isset($object->type)) { + // Let PHP free the $node object when we are done. Working directly on the + // incoming $object causes memory leak issues on long-running scripts such + // as migrations. See http://drupal.org/node/736440. + $node = drupal_clone($object); + $content_type = content_types($node->type); + $node->build_mode = 'token'; + $node->content = array(); + content_view($node); + // The formatted values will only be known after the content has been rendered. + drupal_render($node->content); + content_alter($node); + + $field_types = _content_field_types(); + foreach ($content_type['fields'] as $field_name => $field) { + $items = isset($node->{$field_name}) ? $node->{$field_name} : array(); + $function = $field_types[$field['type']]['module'] . '_token_values'; + if (!empty($items) && function_exists($function)) { + $token_values = (array) $function('field', $items, $options); + foreach ($token_values as $token => $value) { + $tokens[$field_name .'-'. $token] = $value; + } + } + } + } + } + return $tokens; +} + +function content_token_list($type = 'all') { + if ($type == 'node' || $type == 'all') { + $list = array(); + $field_types = _content_field_types(); + + foreach (content_fields() as $field) { + $sub_list = array(); + $function = $field_types[$field['type']]['module'] . '_token_list'; + if (function_exists($function)) { + $sub_list = $function('field'); + foreach ($sub_list as $category => $token_list) { + foreach ($token_list as $token => $description) { + $list['CCK '. $category][$field['field_name'] .'-'. $token] = $description; + } + } + } + } + + return $list; + } +} + +if (module_exists('nodereference')) { + function nodereference_token_list($type = 'all') { + if ($type == 'field' || $type == 'all') { + $tokens = array(); + + $tokens['node reference']['nid'] = t('Referenced node ID'); + $tokens['node reference']['title'] = t('Referenced node title'); + $tokens['node reference']['title-raw'] = t('Referenced node unfiltered title. WARNING - raw user input.'); + $tokens['node reference']['link'] = t("Formatted html link to the referenced node."); + $tokens['node reference']['path'] = t("Relative path alias to the referenced node."); + $tokens['node reference']['url'] = t("Absolute path alias to the referenced node."); + + return $tokens; + } + } + + function nodereference_token_values($type, $object = NULL, $options = array()) { + if ($type == 'field') { + $item = $object[0]; + + $title = is_numeric($item['nid']) ? _nodereference_titles($item['nid']) : ''; + $tokens['nid'] = $item['nid']; + $tokens['title'] = $title ? check_plain($title) : ''; + $tokens['title-raw'] = $title; + $tokens['link'] = isset($item['view']) ? $item['view'] : ''; + $tokens['path'] = is_numeric($item['nid']) ? url('node/' . $item['nid']) : ''; + $tokens['url'] = is_numeric($item['nid']) ? url('node/' . $item['nid'], array('absolute' => TRUE)) : ''; + + return $tokens; + } + } +} + +if (module_exists('number')) { + function number_token_list($type = 'all') { + if ($type == 'field' || $type == 'all') { + $tokens = array(); + + $tokens['number']['raw'] = t('Raw number value'); + $tokens['number']['formatted'] = t('Formatted number value'); + + return $tokens; + } + } + + function number_token_values($type, $object = NULL, $options = array()) { + if ($type == 'field') { + $item = $object[0]; + + $tokens['raw'] = $item['value']; + $tokens['formatted'] = isset($item['view']) ? $item['view'] : ''; + + return $tokens; + } + } +} + +if (module_exists('text')) { + function text_token_list($type = 'all') { + if ($type == 'field' || $type == 'all') { + $tokens = array(); + + $tokens['text']['raw'] = t('Raw, unfiltered text'); + $tokens['text']['formatted'] = t('Formatted and filtered text'); + + return $tokens; + } + } + + function text_token_values($type, $object = NULL, $options = array()) { + if ($type == 'field') { + $item = $object[0]; + + $tokens['raw'] = $item['value']; + $tokens['formatted'] = isset($item['view']) ? $item['view'] : ''; + return $tokens; + } + } +} + +if (module_exists('userreference')) { + function userreference_token_list($type = 'all') { + if ($type == 'field' || $type == 'all') { + $tokens = array(); + + $tokens['user reference']['uid'] = t('Referenced user ID'); + $tokens['user reference']['name'] = t('Referenced user name'); + $tokens['user reference']['link'] = t('Formatted HTML link to referenced user'); + $tokens['user reference']['path'] = t("Relative path alias to the referenced user."); + $tokens['user reference']['url'] = t("Absolute path alias to the referenced user."); + + return $tokens; + } + } + + function userreference_token_values($type, $object = NULL, $options = array()) { + if ($type == 'field') { + $item = $object[0]; + + $tokens['uid'] = $item['uid']; + $tokens['name'] = isset($item['view']) ? strip_tags($item['view']) : ''; + $tokens['link'] = isset($item['view']) ? $item['view'] : ''; + $tokens['path'] = is_numeric($item['uid']) ? url('user/' . $item['uid']) : ''; + $tokens['url'] = is_numeric($item['uid']) ? url('user/' . $item['uid'], array('absolute' => TRUE)) : ''; + + return $tokens; + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/panels/content_types/content_field.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/panels/content_types/content_field.inc new file mode 100644 index 0000000000000000000000000000000000000000..58888e95e6908b7c57f4dba591ab7854c4cd0f99 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/panels/content_types/content_field.inc @@ -0,0 +1,215 @@ +<?php +// $Id$ + +/** + * @file + * This file provides a CTools content type for fields. + */ + +/** + * Callback function to supply a list of content types. + */ +function content_content_field_ctools_content_types() { + return array( + 'title' => t('Content field'), + 'defaults' => array('label' => '', 'formatter' => ''), + 'content type' => 'content_content_field_content_type_content_type', + ); +} + +/** + * Return all field content types available. + */ +function content_content_field_content_type_content_types() { + // This will hold all the individual field content types. + $types = array(); + + // Get all fields on the site. + $field_types = _content_field_types(); + + foreach (content_types() as $type_name => $type) { + foreach ($type['fields'] as $field_name => $field) { + if (!isset($types[$field_name])) { + $types[$field_name] = array( + 'category' => t('Node'), + 'icon' => 'icon_cck_field.png', + 'title' => t('Field: @widget_label (@field_name) - @field_type', array( + '@widget_label' => t($field['widget']['label']), + '@field_name' => $field_name, + '@field_type' => t($field_types[$field['type']]['label']), + )), + 'description' => t('Field on the referenced node.'), + 'types' => array(), + ); + if (isset($field_types[$field['type']]['content_icon'])) { + $types[$field_name]['icon'] = $field_types[$field['type']]['content_icon']; + } + } + $types[$field_name]['types'][$type_name] = $type['name']; + } + } + + // Create the required context for each field related to the content types. + foreach ($types as $field_name => $field_content_type) { + $types[$field_name]['required context'] = new ctools_context_required(t('Node'), 'node', array( + 'type' => array_keys($types[$field_name]['types']), + )); + unset($types[$field_name]['types']); + } + + return $types; +} + +/** + * Just one subtype. + * + * Ordinarily this function is meant to get just one subtype. However, we are + * using it to deal with the fact that we have changed the subtype names. This + * lets us translate the name properly. + */ +function content_content_field_content_type_content_type($subtype) { + // Previous versions of CCK included the content type as part of the subtype. + // This allows those to continue to sort of work, at least during render. + if (strpos($subtype, ':') !== FALSE) { + list($content_type, $subtype) = explode(':', $subtype, 2); + } + + $types = content_content_field_content_type_content_types(); + if (isset($types[$subtype])) { + return $types[$subtype]; + } +} + +/** + * Output function for the 'field' content type. + */ +function content_content_field_content_type_render($subtype, $conf, $panel_args, $context) { + // Previous versions of CCK included the content type as part of the subtype. + // This allows those to continue to sort of work, at least during render. + if (strpos($subtype, ':') !== FALSE) { + list($content_type, $subtype) = explode(':', $subtype, 2); + } + + if (is_array($context)) { + $context = array_pop($context); + } + // If we do not have a node, then we cannot generate output. + if (!isset($context->data)) { + return; + } + $node = drupal_clone($context->data); + + // Extract the node type from the node in context, the field name from the + // panels content type subtype, and get the content field structure. + $field_name = $subtype; + $field = content_fields($field_name, $node->type); + + // Get the formatter that was selected in the settings dialog. + $formatter = $conf['formatter']; + + // Check view access to the field. + if (!content_access('view', $field, NULL, $node)) { + return; + } + + // Force panel settings into the field's display settings. + $field['display_settings']['label']['format'] = $conf['label'] == 'normal' || !empty($conf['override_title']) ? 'hidden' : $conf['label']; + $field['display_settings']['full']['format'] = $formatter; + $node->build_mode = NODE_BUILD_NORMAL; + // TODO : allow panel-specific template suggestions for content-field.tpl.php ? + + $output = content_view_field($field, $node); + + $block = new stdClass(); + $block->module = 'content'; + $block->delta = $field_name; + if ($conf['label'] == 'normal') { + $block->title = t($field['widget']['label']); + } + $block->content = $output; + + return $block; +} + +/** + * Returns a settings form for the custom type. + */ +function content_content_field_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['label'] = array( + '#type' => 'select', + '#title' => t('Field label'), + '#default_value' => isset($conf['label']) ? $conf['label'] : '', + '#options' => array( + 'normal' => t('Block title'), + 'above' => t('Above'), + 'inline' => t('Inline'), + ), + '#description' => t('Configure how the label is going to be displayed. This option takes no effect when "Override title" option is enabled, the specified block title is displayed instead.'), + ); + + // Extract the field name from the panels content type subtype. + $field_name = $form_state['subtype_name']; + + // Previous versions of CCK included the content type as part of the subtype. + // This allows those to continue to sort of work. + if (strpos($field_name, ':') !== FALSE) { + list($content_type, $field_name) = explode(':', $field_name, 2); + } + + // Get all the information about our field. + $field = content_fields($field_name); + + // Get information about all the field types on the site. + $field_types = _content_field_types(); + + // Get the information about the type that our field is. + $type_info = $field_types[$field['type']]; + + // Put the possible formatters for our type into an array. + $options = array(); + foreach ($type_info['formatters'] as $formatter_name => $formatter) { + $options[$formatter_name] = $formatter['label']; + } + + $form['formatter'] = array( + '#type' => 'select', + '#title' => t('Field formatter'), + '#default_value' => isset($conf['formatter']) ? $conf['formatter'] : 'default', + '#options' => $options, + '#description' => t('Select a formatter.'), + '#required' => TRUE, + ); +} + +function content_content_field_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Admin title for field content type. + */ +function content_content_field_content_type_admin_title($subtype, $conf, $context) { + // Previous versions of CCK included the content type as part of the subtype. + // This allows those to continue to sort of work, at least during render. + if (strpos($subtype, ':') !== FALSE) { + list($content_type, $subtype) = explode(':', $subtype, 2); + } + + // Get all fields on the site. + $field_types = _content_field_types(); + + // Get all the information about our field. + $field = content_fields($subtype); + + return t('"@s" field: @widget_label (@field_name) - @field_type', array( + '@s' => $context->identifier, + '@widget_label' => t($field['widget']['label']), + '@field_name' => $subtype, + '@field_type' => t($field_types[$field['type']]['label']), + )); +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/panels/content_types/icon_cck_field.png b/drupal/sites/default/boinc/modules/contrib/cck/includes/panels/content_types/icon_cck_field.png new file mode 100644 index 0000000000000000000000000000000000000000..d33aae585d1de331df5dcccb2696cd4f5014a115 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/includes/panels/content_types/icon_cck_field.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/content.views.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/content.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..071930fe61b5cda275fb04ed38447973edbccdee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/content.views.inc @@ -0,0 +1,375 @@ +<?php +// $Id$ + +/** + * @file + * Interface between content.module and views.module. + */ + +// Include the files defining the classes we extend. +// This is needed in case the /cck folder lives in the main +// /modules folder (views_module_include() will then load +// content.views.inc before node.views.inc) +module_load_include('inc', 'views', 'modules/node.views'); + +/** + * Implementation of hook_views_handlers(). + */ +function content_views_handlers() { + return array( + 'info' => array( + 'path' => drupal_get_path('module', 'content') . '/includes/views/handlers', + ), + 'handlers' => array( + + // argument handlers + 'content_handler_argument' => array( + 'parent' => 'views_handler_argument', + ), + 'content_handler_argument_string' => array( + 'parent' => 'views_handler_argument_string', + ), + 'content_handler_argument_numeric' => array( + 'parent' => 'views_handler_argument_numeric', + ), + 'content_handler_argument_reference' => array( + 'parent' => 'content_handler_argument_numeric', + ), + 'content_handler_argument_many_to_one' => array( + 'parent' => 'views_handler_argument_many_to_one', + ), + + // field handlers + 'content_handler_field' => array( + 'parent' => 'views_handler_field_node', + ), + 'content_handler_field_multiple' => array( + 'parent' => 'content_handler_field', + ), + + // filter handlers + 'content_handler_filter_string' => array( + 'parent' => 'views_handler_filter_string', + ), + 'content_handler_filter_numeric' => array( + 'parent' => 'views_handler_filter_numeric', + ), + 'content_handler_filter_float' => array( + 'parent' => 'views_handler_filter_float', + ), + 'content_handler_filter_many_to_one' => array( + 'parent' => 'views_handler_filter_many_to_one', + ), + + // relationship handlers + 'content_handler_relationship' => array( + 'parent' => 'views_handler_relationship', + ), + + // sort handlers + 'content_handler_sort' => array( + 'parent' => 'views_handler_sort', + ), + ), + ); +} + +/** + * Implementation of hook_views_plugins. + * + * Defines some plugins used by the Views modes for + * nodereference and userreference. + */ +function content_views_plugins() { + $plugins = array( + 'module' => 'content', // This just tells our themes are elsewhere. + 'display' => array( + 'content_simple' => array( + 'path' => drupal_get_path('module', 'content') . '/includes/views/handlers', + // Those strings are not translated for now. + // We'll need to change that if / when we remove 'no ui' + 'title' => 'Simple', // TODO: better name ? (currently not displayed anyway) + 'help' => 'Destination-agnostic display. Mostly useful for programmatic views.', + 'handler' => 'content_plugin_display_simple', + 'no ui' => TRUE, // Programmatic use only. + 'uses hook menu' => FALSE, + 'use ajax' => FALSE, + 'use pager' => FALSE, + 'accept attachments' => FALSE, + ), + 'content_references' => array( + 'path' => drupal_get_path('module', 'content') . '/includes/views/handlers', + // Those strings are not translated for now. + // We'll need to change that if / when we remove 'no ui' + 'title' => 'Simple - for reference fields', // TODO: better name ? (currently not displayed anyway) + 'help' => 'Destination-agnostic display. Mostly useful for programmatic views.', + 'parent' => 'content_simple', + 'handler' => 'content_plugin_display_references', + 'no ui' => TRUE, // Programmatic use only. + 'uses hook menu' => FALSE, + 'use ajax' => FALSE, + 'use pager' => FALSE, + 'accept attachments' => FALSE, + ), + ), + 'style' => array( + 'content_php_array_autocomplete' => array( + 'path' => drupal_get_path('module', 'content') . '/includes/views/handlers', + // Those strings are not translated for now. + // We'll need to change that if / when we remove 'no ui' + 'title' => 'Results array (with title)', + 'help' => 'Returns the view as a PHP array of names + rendered rows.', + 'handler' => 'content_plugin_style_php_array_ac', + 'no ui' => TRUE, // Programmatic use only. + 'uses row plugin' => TRUE, + 'uses fields' => TRUE, + 'type' => 'content_simple', + 'even empty' => TRUE, + ), + ), + ); + return $plugins; +} + +/** + * Implementation of hook_views_data(). + * + * Exposes all fields to the views system. + */ +function content_views_data() { + $data = array(); + foreach (content_fields() as $field) { + $module = $field['module']; + $result = (array) module_invoke($module, 'field_settings', 'views data', $field); + drupal_alter('field_settings', $result, 'views data', $field); + if (empty($result)) { + $result = content_views_field_views_data($field); + } + if (is_array($result)) { + $data = array_merge($data, $result); + } + } + return $data; +} + + +function content_views_field_views_data($field) { + $field_types = _content_field_types(); + + // Check the field module is available. + // TODO: is this really how we should do it ? + if (isset($field_types[$field['type']])) { + $db_info = content_database_info($field); + + // Field modules that do not store data in the database + // should not create views data tables. + if (empty($db_info['columns'])) { + return; + } + + $table_alias = content_views_tablename($field); + + $types = array(); + foreach (content_types() as $type) { + if (isset($type['fields'][$field['field_name']])) { + // TODO : run check_plain here instead of on the imploded string below ? + $types[] = $type['name']; + } + } + + $data = array(); + $data['table']['group'] = t('Content'); + $data['table']['join']['node'] = array( + 'table' => $db_info['table'], + 'left_field' => 'vid', + 'field' => 'vid', + ); + $data['table']['join']['node_revisions'] = array( + 'table' => $db_info['table'], + 'left_field' => 'vid', + 'field' => 'vid', + ); + + // Build the list of columns enabled for default views integration. + $db_columns = array(); + $additional_fields = array(); + foreach ($db_info['columns'] as $column => $attributes) { + // Select explicitly enabled field columns. + if (!empty($attributes['views'])) { + $db_columns[$column] = $attributes; + } + // Ensure all columns are retrieved. + $additional_fields[$attributes['column']] = $attributes['column']; + } + // Pick up the first column when none has been explicitly enabled + // (pre CCK 2.2 backwards compatibility). + if (empty($db_columns)) { + // Can't use array_slice(), it won't work in PHP4 for assoc array. + foreach ($db_info['columns'] as $column => $attributes) { + $db_columns[$column] = $attributes; + break; + } + } + $columns = array(); + $db_fields = array(); + $arguments = array(); + $filters = array(); + foreach ($db_columns as $column => $attributes) { + $columns[] = $column; + $db_fields[] = $attributes['column']; + $sorts[] = !empty($attributes['sortable']) ? TRUE : FALSE; + + // Identify likely filters and arguments for each column based on field type. + switch ($attributes['type']) { + case 'int': + case 'mediumint': + case 'tinyint': + case 'bigint': + case 'serial': + $filters[] = 'content_handler_filter_numeric'; + $arguments[] = 'content_handler_argument_numeric'; + break; + case 'numeric': + case 'float': + $filters[] = 'content_handler_filter_float'; + $arguments[] = 'content_handler_argument_numeric'; + break; + + case 'text': + case 'blob': + // TODO add markup handlers for these types + default: + $filters[] = 'content_handler_filter_string'; + $arguments[] = 'content_handler_argument_string'; + break; + } + } + + // Provide automatic filters, sorts, and arguments for each column, not just the first. + $db_fields_count = count($db_fields); + foreach ($db_fields as $i => $db_field) { + $label_truncated = truncate_utf8(t($field['widget']['label']), 10, TRUE); + if ($db_fields_count == 1) { + $title = t('@label (!name)', array('@label' => t($field['widget']['label']), '!name' => $field['field_name'])); + $title_short = check_plain($label_truncated); + } + else { + $title = t('@label (!name) - !column', array('@label' => t($field['widget']['label']), '!name' => $field['field_name'], '!column' => $columns[$i])); + $title_short = t('@label-truncated - !column', array('@label-truncated' => $label_truncated, '!column' => $columns[$i])); + } + + $data[$db_field] = array( + 'group' => t('Content'), + 'title' => $title, + 'title short' => $title_short, + 'help' => t($field_types[$field['type']]['label']) .' - '. t('Appears in: @types', array('@types' => implode(', ', $types))), + ); + if ($i == 0) { + $data[$db_field]['field'] = array( + 'title' => t('@label (!name)', array('@label' => t($field['widget']['label']), '!name' => $field['field_name'])), + 'title short' => check_plain($label_truncated), + 'field' => $db_field, + 'table' => $db_info['table'], + 'handler' => 'content_handler_field_multiple', + 'click sortable' => $sorts[$i], + 'additional fields' => $additional_fields, + 'content_field_name' => $field['field_name'], + 'access callback' => 'content_access', + 'access arguments' => array('view', $field), + ); + } + $data[$db_field]['argument'] = array( + 'field' => $db_field, + 'table' => $db_info['table'], + 'handler' => $arguments[$i], + 'additional fields' => $additional_fields, + 'content_field_name' => $field['field_name'], + 'empty field name' => t('<No value>'), + ); + $data[$db_field]['filter'] = array( + 'field' => $db_field, + 'table' => $db_info['table'], + 'handler' => $filters[$i], + 'additional fields' => $additional_fields, + 'content_field_name' => $field['field_name'], + 'allow empty' => TRUE, + ); + if (!empty($sorts[$i])) { + $data[$db_field]['sort'] = array( + 'field' => $db_field, + 'table' => $db_info['table'], + 'handler' => 'content_handler_sort', + 'additional fields' => $additional_fields, + 'content_field_name' => $field['field_name'], + ); + } + } + + // Expose additional delta column for multiple value fields. + if ($field['multiple']) { + $title = t('@label (!name) - delta', array('@label' => t($field['widget']['label']), '!name' => $field['field_name'])); + $title_short = t('@label-truncated - delta', array('@label-truncated' => $label_truncated)); + + $db_field = 'delta'; + $data[$db_field] = array( + 'group' => t('Content'), + 'title' => $title, + 'title short' => $title_short, + 'help' => t('Delta - Appears in: @types', array('@types' => implode(', ', $types))), + ); + $data[$db_field]['field'] = array( + 'title' => $title, + 'title short' => $title_short, + 'field' => $db_field, + 'table' => $db_info['table'], + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + 'additional fields' => $additional_fields, + 'access callback' => 'content_access', + 'access arguments' => array('view', $field), + ); + $data[$db_field]['argument'] = array( + 'field' => $db_field, + 'table' => $db_info['table'], + 'handler' => 'views_handler_argument_numeric', + 'additional fields' => $additional_fields, + 'empty field name' => t('<No value>'), + ); + $data[$db_field]['filter'] = array( + 'field' => $db_field, + 'table' => $db_info['table'], + 'handler' => 'views_handler_filter_numeric', + 'additional fields' => $additional_fields, + 'allow empty' => TRUE, + ); + $data[$db_field]['sort'] = array( + 'field' => $db_field, + 'table' => $db_info['table'], + 'handler' => 'views_handler_sort', + 'additional fields' => $additional_fields, + ); + } + + return array($table_alias => $data); + } +} + +/** + * Helper function so it is possible to change the Views tablename + * in the future without re-writing code. + */ +function content_views_tablename($field) { + return 'node_data_'. $field['field_name']; +} + +function theme_content_view_multiple_field($items, $field, $values) { + $output = ''; + $i = 0; + foreach ($items as $item) { + if (!empty($item) || $item == '0') { + $output .= '<div class="field-item field-item-'. $i .'">'. $item .'</div>'; + $i++; + } + } + return $output; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/content.views_convert.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/content.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..aaa94f90c11b24e4e4d460d52832db54f45714e3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/content.views_convert.inc @@ -0,0 +1,72 @@ +<?php +// $Id$ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implementation of hook_views_convert(). + * + * Intervene to convert field values from the Views 1 format to the + * Views 2 format. Intervene only if $view->add_item() won't produce + * the right results, usually needed to set field options or values. + */ +function content_views_convert($display, $type, &$view, $views_field) { + static $views_fields; + + if (empty($views_fields)) { + $views_fields = array(); + $types = content_types(); + foreach ($types as $ctype) { + foreach ($ctype['fields'] as $field) { + $module = $field['module']; + $result = (array) module_invoke($module, 'field_settings', 'views data', $field); + drupal_alter('field_settings', $result, 'views data', $field); + if (empty($result)) { + // The views field name had the column name appended, + // like field_name_value or field_username_uid. + $column = array_shift(array_keys($field['columns'])); + $views_fields[$field['field_name'] .'_'. $column] = $field; + } + } + } + } + + // Is this a field that CCK should handle? If not, return. + if (!in_array($views_field['field'], array_keys($views_fields))) { + return; + } + + // Now update values, options, etc. to those selected in the imported view. + switch ($type) { + case 'field': + $view->display[$display]->display_options['fields'][$views_field['field']]['format'] = $views_field['options']; + if ($views_field['handler'] == 'content_views_field_handler_group') { + $view->display[$display]->display_options['fields'][$views_field['field']]['multiple']['group'] = 1; + } + else { + $view->display[$display]->display_options['fields'][$views_field['field']]['multiple']['group'] = 0; + } + return; + + case 'filter': + // TODO + return; + + case 'exposed_filter': + // TODO + return; + + case 'argument': + // TODO + return; + + case 'sort': + // TODO + break; + + } + return; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument.inc new file mode 100644 index 0000000000000000000000000000000000000000..98e3eb8a0e3fb3ee194121fbacc41d175de8a273 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument.inc @@ -0,0 +1,18 @@ +<?php +// $Id$ + +/** + * @file + * The subclass simply adds properties, + * for field-specific subclasses to use if they need to. + */ +class content_handler_argument extends views_handler_argument { + var $content_field; + + function construct() { + parent::construct(); + + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_many_to_one.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_many_to_one.inc new file mode 100644 index 0000000000000000000000000000000000000000..09e48936c7cebae03944f90aab3cfddf4aad3c6e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_many_to_one.inc @@ -0,0 +1,48 @@ +<?php +// $Id$ + +/** + * @file + * Handler for 'content_handler_argument_many_to_one' style. + */ +class content_handler_argument_many_to_one extends views_handler_argument_many_to_one { + var $content_field; + + function construct() { + parent::construct(); + + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + } + + function summary_name($data) { + $options = $this->allowed_values(); + $value = $data->{$this->name_alias}; + if (isset($options[$value])) { + $value = $options[$value]; + } + else { + $value = parent::summary_name($data); + } + + return $value; + } + + function title_query() { + $options = $this->allowed_values(); + $values = $this->value; + foreach ($values as $key => $value) { + if (isset($options[$value])) { + $values[$key] = $options[$value]; + } + } + return $values; + } + + function allowed_values() { + $field = $this->content_field; + $function = $field['module'] .'_allowed_values'; + $options = function_exists($function) ? $function($field) : content_allowed_values($field); + return (array) $options; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_numeric.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..9a50b95a298fe216c24d8c86a8fd71db04769653 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_numeric.inc @@ -0,0 +1,18 @@ +<?php +// $Id$ + +/** + * @file + * The subclass simply adds properties, + * for field-specific subclasses to use if they need to. + */ +class content_handler_argument_numeric extends views_handler_argument_numeric { + var $content_field; + + function construct() { + parent::construct(); + + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_reference.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_reference.inc new file mode 100644 index 0000000000000000000000000000000000000000..96473bb6820a981decb55897caa953789bc782e1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_reference.inc @@ -0,0 +1,25 @@ +<?php +// $Id$ + +/** + * @file + * Provide handler to replace reference with title. + */ +class content_handler_argument_reference extends content_handler_argument_numeric { + /** + * Override the behavior of title(). + */ + function title_query() { + $titles = array(); + $placeholders = implode(', ', array_fill(0, sizeof($this->value), '%d')); + + $table_data = views_fetch_data($this->name_table); + $table = array_shift($table_data['table']['join']); + + $result = db_query("SELECT $this->name_field AS title FROM {". $table['table'] ."} WHERE ". $table['field'] ." IN ($placeholders)", $this->value); + while ($row = db_fetch_object($result)) { + $titles[] = check_plain($row->title); + } + return $titles; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_string.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_string.inc new file mode 100644 index 0000000000000000000000000000000000000000..b17ade03ca2ecd8a71286b76e663a4fd9de9e110 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_argument_string.inc @@ -0,0 +1,18 @@ +<?php +// $Id$ + +/** + * @file + * The subclass simply adds properties, + * for field-specific subclasses to use if they need to. + */ +class content_handler_argument_string extends views_handler_argument_string { + var $content_field; + + function construct() { + parent::construct(); + + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_field.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_field.inc new file mode 100644 index 0000000000000000000000000000000000000000..f8dfc2f161f1fbb9d669d1c41b6ddf222b6b9857 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_field.inc @@ -0,0 +1,229 @@ +<?php +// $Id$ + +/** + * @file + * The subclass adds basic field and formatter info, + * for field-specific subclasses to use if they need to. + * + * Fields could extend this class if they want field and formatter handling + * but don't want the multiple value grouping options created by + * content_handler_field_multiple. + */ +class content_handler_field extends views_handler_field_node { + var $content_field; + + function construct() { + parent::construct(); + $this->content_field = content_fields($this->definition['content_field_name']); + } + + function init(&$view, $options) { + $field = $this->content_field; + parent::init($view, $options); + if ($field['multiple']) { + $this->additional_fields['delta'] = 'delta'; + } + // Make sure we grab enough information to build a pseudo-node with enough + // credentials at render-time. + $this->additional_fields['type'] = array('table' => 'node', 'field' => 'type'); + $this->additional_fields['nid'] = array('table' => 'node', 'field' => 'nid'); + $this->additional_fields['vid'] = array('table' => 'node', 'field' => 'vid'); + } + + function option_definition() { + $options = parent::option_definition(); + $field = $this->content_field; + + // Override views_handler_field_node's default label + $options['label'] = array('default' => '', 'translatable' => TRUE); + $options['label_type'] = array('default' => 'widget'); + $options['format'] = array('default' => 'default'); + + return $options; + } + + /** + * Provide formatter option. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + // TODO: do we want the 'link to node' checkbox ? + // That's usually formatters business... + + $field = $this->content_field; + $options = $this->options; + + $form['label_type'] = array( + '#title' => t('Label'), + '#type' => 'radios', + '#options' => array( + 'none' => t('None'), + 'widget' => t('Widget label (@label)', array('@label' => $field['widget']['label'])), + 'custom' => t('Custom'), + ), + '#default_value' => $options['label_type'], + '#weight' => 2, + ); + $form['label'] = array( + '#title' => t('Custom label'), + '#type' => 'textfield', + '#default_value' => $options['label'], + '#process' => array('views_process_dependency'), + '#dependency' => array('radio:options[label_type]' => array('custom')), + '#weight' => 3, + ); + + $field_types = _content_field_types(); + $formatters = array(); + if (is_array($field_types[$field['type']]['formatters'])) { + foreach ($field_types[$field['type']]['formatters'] as $name => $info) { + $formatters[$name] = $info['label']; + } + } + $form['format'] = array( + '#title' => t('Format'), + '#type' => 'select', + '#options' => $formatters, + '#required' => TRUE, + '#default_value' => $options['format'], + '#weight' => 4, + ); + } + + + /** + * Make sure some value is stored as a label. + * + * Don't use t(), since Views' views_handler_field already has + * $this->options['label'] marked as a translatable field. + * + * @see http://drupal.org/node/285470 + */ + function options_submit($form, &$form_state) { + switch ($form_state['values']['options']['label_type']) { + case 'none': + $form_state['values']['options']['label'] = ''; + break; + case 'widget': + $form_state['values']['options']['label'] = $this->content_field['widget']['label']; + break; + } + } + + /** + * @TODO + * Now that we save the label in the submit process above we could + * get rid of this function. Leave it here for now to be sure the + * label works for fields that haven't been updated since this + * change was made, since $this->options['label'] will be missing a + * value until it is updated in the view. + * + * Don't use t(), since Views' views_handler_field already has + * $this->options['label'] marked as a translatable field. + */ + function label() { + $field = $this->content_field; + switch ($this->options['label_type']) { + case 'none': + return ''; + case 'widget': + return $field['widget']['label']; + default: + return $this->options['label']; + } + } + + /** + * Return DIV or SPAN based upon the field's element type. + */ + function element_type($none_supported = FALSE, $default_empty = FALSE) { + // The 'element_type' property denotes Views 3.x ('semantic views' + // functionnality). If the property is set, and not set to '' ("default"), + // let the generic method handle the output. + if (isset($this->options['element_type']) && $this->options['element_type'] !== '') { + return parent::element_type($none_supported, $default_empty); + } + + if ($default_empty) { + return ''; + } + + if (isset($this->definition['element type'])) { + return $this->definition['element type']; + } + + // TODO Figure out exactly when to return a div or a <span>. Any field + // that ever needs to be shown inline in Views UI. It needs to return + // a div for textareas to prevent wrapping a <span> around a <p>. + // Earl says we need to be sure that other fields we don't know + // about won't end up wrapping a span around a block-level element. + if ($this->content_field['widget']['type'] == 'text_textarea') { + return 'div'; + } + else { + return 'span'; + } + } + + function options_validate($form, &$form_state) { } + + /** + * Provide text for the administrative summary + */ + function admin_summary() { + // Display the formatter name. + $field = $this->content_field; + $field_types = _content_field_types(); + if (isset($field_types[$field['type']]['formatters'][$this->options['format']])) { + return t($field_types[$field['type']]['formatters'][$this->options['format']]['label']); + } + } + + function render($values) { + // We're down to a single node here, so we can retrieve the actual field + // definition for the node type being considered. + $field = content_fields($this->content_field['field_name'], $values->{$this->aliases['type']}); + + // If the field does not appear in the node type, then we have no value + // to display, and can just return. + if (empty($field)) { + return ''; + } + + $options = $this->options; + $db_info = content_database_info($field); + + // Build a pseudo-node from the retrieved values. + $node = drupal_clone($values); + $node->type = $values->{$this->aliases['type']}; + $node->nid = $values->{$this->aliases['nid']}; + $node->vid = $values->{$this->aliases['vid']}; + // Some formatters need to behave differently depending on the build_mode + // (for instance: preview), so we provide one. + $node->build_mode = NODE_BUILD_NORMAL; + + $item = array(); + foreach ($db_info['columns'] as $column => $attributes) { + $item[$column] = $values->{$this->aliases[$attributes['column']]}; + } + + $item['#delta'] = $field['multiple'] ? $values->{$this->aliases['delta']} : 0; + + // Render items. + $formatter_name = $options['format']; + if ($formatter = _content_get_formatter($formatter_name, $field['type'])) { + if (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE) { + // Single-value formatter. + $output = content_format($field, $item, $formatter_name, $node); + } + else { + // Multiple values formatter - we actually have only one value to display. + $output = content_format($field, array($item), $formatter_name, $node); + } + return $this->render_link($output, $values); + } + return ''; + } + +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_field_multiple.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_field_multiple.inc new file mode 100644 index 0000000000000000000000000000000000000000..bd31e24f7b9e223c5f305f51cb747b769eb97286 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_field_multiple.inc @@ -0,0 +1,322 @@ +<?php +// $Id$ + +/** + * @file + * An extended subclass for field handling that adds multiple field grouping. + * + * Fields that want multiple value grouping options in addition to basic + * field and formatter handling can extend this class. + */ +class content_handler_field_multiple extends content_handler_field { + var $defer_query; + + function init(&$view, $options) { + $field = $this->content_field; + parent::init($view, $options); + + $this->defer_query = !empty($options['multiple']['group']) && $field['multiple']; + + if ($this->defer_query) { + // Grouped field: ditch the existing additional_fields (field columns + delta). + // In the main query we'll only need: + // - vid, which will be used to retrieve the actual values in pre_render, + // - node type and nid, which wil be used in the pseudo-node used when + // rendering. + $this->additional_fields = array( + 'type' => array('table' => 'node', 'field' => 'type'), + 'nid' => array('table' => 'node', 'field' => 'nid'), + ); + if ($view->base_table == 'node_revisions') { + $this->additional_fields['vid'] = array('table' => 'node_revisions', 'field' => 'vid'); + } + else { + $this->additional_fields['vid'] = array('table' => 'node', 'field' => 'vid'); + } + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['multiple'] = array( + 'contains' => array( + 'group' => array('default' => TRUE), + 'multiple_number' => array('default' => ''), + 'multiple_from' => array('default' => ''), + 'multiple_reversed' => array('default' => FALSE), + ), + ); + + return $options; + } + + /** + * Provide 'group multiple values' option. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $field = $this->content_field; + $options = $this->options; + + $form['multiple'] = array( + '#access' => $field['multiple'], + '#weight' => 1, + ); + $form['multiple']['group'] = array( + '#title' => t('Group multiple values'), + '#type' => 'checkbox', + '#default_value' => $options['multiple']['group'], + '#description' => t('If unchecked, each item in the field will create a new row, which may appear to cause duplicates. This setting is not compatible with click-sorting in table displays.'), + ); + // Make the string translatable by keeping it as a whole rather than + // translating prefix and suffix separately. + list($prefix, $suffix) = explode('@count', t('Show @count value(s)')); + $form['multiple']['multiple_number'] = array( + '#type' => 'textfield', + '#size' => 5, + '#field_prefix' => $prefix, + '#field_suffix' => $suffix, + '#default_value' => $options['multiple']['multiple_number'], + '#prefix' => '<div class="container-inline">', + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-options-multiple-group' => array(TRUE)), + ); + list($prefix, $suffix) = explode('@count', t('starting from @count')); + $form['multiple']['multiple_from'] = array( + '#type' => 'textfield', + '#size' => 5, + '#field_prefix' => $prefix, + '#field_suffix' => $suffix, + '#default_value' => $options['multiple']['multiple_from'], + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-options-multiple-group' => array(TRUE)), + '#description' => t('(first item is 0)'), + ); + $form['multiple']['multiple_reversed'] = array( + '#title' => t('Reversed'), + '#type' => 'checkbox', + '#default_value' => $options['multiple']['multiple_reversed'], + '#suffix' => '</div>', + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-options-multiple-group' => array(TRUE)), + '#description' => t('(start from last values)'), + ); + } + + /** + * Determine if this field is click sortable. + */ + function click_sortable() { + $field = $this->content_field; + $options = $this->options; + + // Grouped fields are not click-sortable. + return !empty($this->definition['click sortable']) && !$this->defer_query; + } + + function query() { + // If this is not a grouped field, use the generic query(). + if (!$this->defer_query) { + return parent::query(); + } + + // Grouped field: do NOT call ensure_my_table, only add additional fields. + $this->add_additional_fields(); + $this->field_alias = $this->aliases['vid']; + } + + function pre_render($values) { + // If there are no values to render (displaying a summary, or query returned no results), + // or if this is not a grouped field, do nothing specific. + if (isset($this->view->build_info['summary']) || empty($values) || !$this->defer_query) { + return parent::pre_render($values); + } + + $field = $this->content_field; + $db_info = content_database_info($field); + $options = $this->options; + + // Build the list of vids to retrieve. + // TODO: try fetching from cache_content first ?? + $vids = array(); + $this->field_values = array(); + foreach ($values as $result) { + if (isset($result->{$this->field_alias})) { + $vids[] = $result->{$this->field_alias}; + } + } + + // It may happend that the multiple values field is related to a non + // required relation for which no node data related to the field being + // processed here is available. + if (empty($vids)) { + return parent::pre_render($values); + } + + // List columns to retrieve. + $alias = content_views_tablename($field); + // Prefix aliases with '_' to avoid clashing with field columns names. + $query_columns = array( + 'vid AS _vid', + "delta as _delta", + // nid is needed to generate the links for 'link to node' option. + 'nid AS _nid', + ); + // The actual field columns. + foreach ($db_info['columns'] as $column => $attributes) { + $query_columns[] = "$attributes[column] AS $column"; + } + $query = 'SELECT '. implode(', ', $query_columns) . + ' FROM {'. $db_info['table'] ."}". + " WHERE vid IN (". implode(',', $vids) .')'. + " ORDER BY _nid ASC, _delta ". ($options['multiple']['multiple_reversed'] ? 'DESC' : 'ASC'); + $result = db_query($query); + + while ($item = db_fetch_array($result)) { + // Clean up the $item from vid and delta. We keep nid for now. + $vid = $item['_vid']; + unset($item['_vid']); + $delta = !empty($item['_delta']) ? $item['_delta'] : 0; + $item['#delta'] = $item['_delta']; + unset($item['_delta']); + $this->field_values[$vid][$delta] = $item; + } + } + + /** + * Return DIV or SPAN based upon the field's element type. + * + * Fields rendered with the 'group multiple' option use <div> markers, + * and thus shouldn't be wrapped in a <span>. + */ + function element_type($none_supported = FALSE, $default_empty = FALSE) { + // If this is not a grouped field, use the parent method. + if (!$this->defer_query) { + return parent::element_type($none_supported, $default_empty); + } + + // The 'element_type' property denotes Views 3.x ('semantic views' + // functionnality). If the property is set, and not set to '' ("default"), + // let the generic method handle the output. + if (isset($this->options['element_type']) && $this->options['element_type'] !== '') { + return parent::element_type($none_supported, $default_empty); + } + + if ($default_empty) { + return ''; + } + + if (isset($this->definition['element type'])) { + return $this->definition['element type']; + } + + return 'div'; + } + + function render($values) { + // If this is not a grouped field, use content_handler_field::render(). + if (!$this->defer_query) { + return parent::render($values); + } + + // We're down to a single node here, so we can retrieve the actual field + // definition for the node type being considered. + $field = content_fields($this->content_field['field_name'], $values->{$this->aliases['type']}); + + // If the field does not appear in the node type, then we have no value + // to display, and can just return. + if (empty($field)) { + return ''; + } + + $options = $this->options; + + $vid = $values->{$this->field_alias}; + if (isset($this->field_values[$vid])) { + // Gather items, respecting the 'Display n values starting from m' settings. + $count_skipped = 0; + $items = array(); + foreach ($this->field_values[$vid] as $item) { + if (empty($options['multiple']['multiple_from']) || ($count_skipped >= $options['multiple']['multiple_from'])) { + if (empty($options['multiple']['multiple_number']) || (count($items) < $options['multiple']['multiple_number'])) { + // Grab the nid - needed for render_link(). + $nid = $item['_nid']; + unset($item['_nid']); + $items[] = $item; + } + else { + break; + } + } + $count_skipped++; + } + + // Build a pseudo-node from the retrieved values. + $node = drupal_clone($values); + // content_format and formatters will need a 'type'. + $node->type = $values->{$this->aliases['type']}; + $node->nid = $values->{$this->aliases['nid']}; + $node->vid = $values->{$this->aliases['vid']}; + + // Some formatters need to behave differently depending on the build_mode + // (for instance: preview), so we provide one. + $node->build_mode = NODE_BUILD_NORMAL; + + // Render items. + $formatter_name = $options['format']; + if ($items && ($formatter = _content_get_formatter($formatter_name, $field['type']))) { + $rendered = array(); + if (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE) { + // Single-value formatter. + foreach ($items as $item) { + $output = content_format($field, $item, $formatter_name, $node); + if (!empty($output)) { + $rendered[] = $this->render_link($output, (object) array('nid' => $nid)); + } + } + } + else { + // Multiple values formatter. + $output = content_format($field, $items, $formatter_name, $values); + if (!empty($output)) { + $rendered[] = $this->render_link($output, (object) array('nid' => $nid)); + } + } + + if (count($rendered) > 1) { + // TODO: could we use generic field display ? + return theme('content_view_multiple_field', $rendered, $field, $values); + } + elseif ($rendered) { + return $rendered[0]; + } + } + } + + return ''; + } + + function render_link($data, $values) { + if (!$this->defer_query) { + return parent::render_link($data, $values); + } + + if (!empty($this->options['link_to_node']) && $data !== NULL && $data !== '') { + if (method_exists('render_as_link', 'views_handler_field')) { + // Views 2.3+ + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/" . $values->{$this->aliases['nid']}; + } + else { + // Views up to 2.2 + return l($data, "node/" . $values->nid, array('html' => TRUE)); + } + } + else { + return $data; + } + } + +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_float.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_float.inc new file mode 100644 index 0000000000000000000000000000000000000000..bf9f3c4f79dfed6c6212911eb3614c0effbaacf8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_float.inc @@ -0,0 +1,26 @@ +<?php +// $Id$ + +/** + * @file + * The subclass simply adds properties, + * for field-specific subclasses to use if they need to. + */ + +// Ensure compatibility with Views pre 2.4, where the +// views_handler_filter_float class lived in views_handler_filter_numeric.inc. +if (!class_exists('views_handler_filter_float')) { + // Manually include the parent class. + $definition = views_fetch_handler_data('views_handler_filter_numeric'); + views_include_handler($definition, 'handler'); +} + +class content_handler_filter_float extends views_handler_filter_float { + var $content_field; + + function construct() { + parent::construct(); + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_many_to_one.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_many_to_one.inc new file mode 100644 index 0000000000000000000000000000000000000000..74b5348d033053b5768b22396e03e9a263965216 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_many_to_one.inc @@ -0,0 +1,42 @@ +<?php +// $Id$ + +/** + * @file + * The subclass simply adds properties, + * for field-specific subclasses to use if they need to. + */ +class content_handler_filter_many_to_one extends views_handler_filter_many_to_one { + var $content_field; + + function construct() { + parent::construct(); + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + $field = $this->content_field; + $this->value_title = $field['widget']['label']; + } + + function get_value_options() { + $this->value_options = $this->allowed_values(); + } + + // Get allowed values from hook_allowed_values(), if any, + // or from content_allowed_values(); + function allowed_values() { + $field = $this->content_field; + $function = $field['module'] .'_allowed_values'; + if ($this->value_form_type == 'select') { + // Select elements accept multidimensional arrays to support optgroups. + $options = function_exists($function) ? $function($field) : content_allowed_values($field, FALSE); + // For selects, HTML should be filtered out and entities left unencoded. + // See content_allowed_values / content_filter_xss / filter_xss. + content_allowed_values_filter_html($options); + } + else { + $options = function_exists($function) ? $function($field) : content_allowed_values($field); + } + return (array) $options; + } + +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_numeric.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..1c4a23a67a6852d43e512fe10e13eff9403e2c04 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_numeric.inc @@ -0,0 +1,17 @@ +<?php +// $Id$ + +/** + * @file + * The subclass simply adds properties, + * for field-specific subclasses to use if they need to. + */ +class content_handler_filter_numeric extends views_handler_filter_numeric { + var $content_field; + + function construct() { + parent::construct(); + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_string.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_string.inc new file mode 100644 index 0000000000000000000000000000000000000000..9901e91e2bc22a27f795169554027e8eb0771bd7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_string.inc @@ -0,0 +1,17 @@ +<?php +// $Id$ + +/** + * @file + * The subclass simply adds properties, + * for field-specific subclasses to use if they need to. + */ +class content_handler_filter_string extends views_handler_filter_string { + var $content_field; + + function construct() { + parent::construct(); + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_relationship.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_relationship.inc new file mode 100644 index 0000000000000000000000000000000000000000..136e193f84b5c9d13979491d6a5d02f4df0e5f37 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_relationship.inc @@ -0,0 +1,73 @@ +<?php +// $Id$ + +/** + * @file + * Handles content relationships and deals properly with multiple + * values by allowing the views administrator to select deltas. + */ +class content_handler_relationship extends views_handler_relationship { + var $content_field; + + function construct() { + parent::construct(); + + $this->content_field = content_fields($this->definition['content_field_name']); + } + + function option_definition() { + $options = parent::option_definition(); + $options['delta'] = array('default' => -1); + + return $options; + } + + /** + * Add a delta selector for multiple fields. + */ + function options_form(&$form, &$form_state) { + $field = $this->content_field; + parent::options_form($form, $form_state); + + // Only add the form gadget if the field is multiple. + if ($field['multiple']) { + $max_delta = $field['multiple']; + // 1 means unlimited. + if ($max_delta == 1) { + $max_delta = 10; + } + + $options = array('-1' => t('All')); + for ($i = 0; $i < $max_delta; $i++) { + $options[$i] = $i + 1; + } + $form['delta'] = array( + '#type' => 'select', + '#options' => $options, + '#default_value' => $this->options['delta'], + '#title' => t('Delta'), + '#description' => t('The delta allows you to select which item in a multiple value field to key the relationship off of. Select "1" to use the first item, "2" for the second item, and so on. If you select "All", each item in the field will create a new row, which may appear to cause duplicates.'), + ); + } + } + + function ensure_my_table() { + if (!isset($this->table_alias)) { + $join = $this->get_join(); + if (!isset($join->extra)) { + $join->extra = array(); + } + $delta = isset($this->options['delta']) ? $this->options['delta'] : -1; + if ($delta != -1) { + $join->extra[] = array( + 'field' => 'delta', + 'value' => $delta, + 'numeric' => TRUE, + ); + } + + $this->table_alias = $this->query->add_table($this->table, $this->relationship, $join); + } + return $this->table_alias; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_sort.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_sort.inc new file mode 100644 index 0000000000000000000000000000000000000000..1a3ad7cbacdf81a972604f696069b95dd285116f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_sort.inc @@ -0,0 +1,74 @@ +<?php +// $Id$ + +/** + * @file + * Handles sorts and deals properly with multiple + * values by allowing the views administrator to select deltas. + */ +class content_handler_sort extends views_handler_sort { + var $content_field; + + function construct() { + parent::construct(); + + $this->content_field = content_fields($this->definition['content_field_name']); + $this->additional_fields = $this->definition['additional fields']; + } + + function option_definition() { + $options = parent::option_definition(); + $options['delta'] = array('default' => -1); + + return $options; + } + + /** + * Add a delta selector for multiple fields. + */ + function options_form(&$form, &$form_state) { + $field = $this->content_field; + parent::options_form($form, $form_state); + + // Only add the form gadget if the field is multiple. + if ($field['multiple']) { + $max_delta = $field['multiple']; + // 1 means unlimited. + if ($max_delta == 1) { + $max_delta = 10; + } + + $options = array('-1' => t('All')); + for ($i = 0; $i < $max_delta; $i++) { + $options[$i] = $i + 1; + } + $form['delta'] = array( + '#type' => 'select', + '#options' => $options, + '#default_value' => $this->options['delta'], + '#title' => t('Delta'), + '#description' => t('The delta allows you to select which item in a multiple value field will be used for sorting. Select "1" to use the first item, "2" for the second item, and so on. If you select "All", each item in the field will create a new row, which may appear to cause duplicates.'), + ); + } + } + + function ensure_my_table() { + if (!isset($this->table_alias)) { + $join = $this->get_join(); + if (!isset($join->extra)) { + $join->extra = array(); + } + $delta = isset($this->options['delta']) ? $this->options['delta'] : -1; + if ($delta != -1) { + $join->extra[] = array( + 'field' => 'delta', + 'value' => $delta, + 'numeric' => TRUE, + ); + } + + $this->table_alias = $this->query->ensure_table($this->table, $this->relationship, $join); + } + return $this->table_alias; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_display_simple.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_display_simple.inc new file mode 100644 index 0000000000000000000000000000000000000000..e82531657e75c45e2b42ba830ad4a6531f274d82 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_display_simple.inc @@ -0,0 +1,43 @@ +<?php +// $Id$ + +/** + * @file + * Handler for 'content_simple' display. + */ +class content_plugin_display_simple extends views_plugin_display { + function execute() { + return $this->view->render($this->display->id); + } + + function render() { + return !empty($this->view->result) || !empty($this->view->style_plugin->definition['even empty']) ? $this->view->style_plugin->render($this->view->result) : ''; + } + + function uses_exposed() { + return FALSE; + } +} + +class content_plugin_display_references extends content_plugin_display_simple { + function query() { + $options = $this->get_option('content_options'); + + if ($options['string'] !== '') { + $like = $GLOBALS["db_type"] == 'pgsql' ? "ILIKE" : "LIKE"; + $match_clauses = array( + 'contains' => "$like '%%%s%%'", + 'equals' => "= '%s'", + 'starts_with' => "$like '%s%%'", + ); + $clause = isset($match_clauses[$options['match']]) ? $match_clauses[$options['match']] : $match_clauses['contains']; + $alias = $this->view->query->ensure_table($options['table']); + $this->view->query->add_where(NULL, "$alias.$options[field_string] $clause", $options['string']); + } + elseif ($options['ids']) { + $alias = $this->view->query->ensure_table($options['table']); + $this->view->query->add_where(NULL, "$alias.$options[field_id] IN (" . db_placeholders($options['ids']) . ')', $options['ids']); + } + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_style_php_array_ac.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_style_php_array_ac.inc new file mode 100644 index 0000000000000000000000000000000000000000..abff82d4f08783dad945c4e77b11d1d89ac1b8cd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_style_php_array_ac.inc @@ -0,0 +1,34 @@ +<?php +// $Id$ + +/** + * @file + * Handler for 'content_php_array_autocomplete' style. + */ +class content_plugin_style_php_array_ac extends views_plugin_style { + function render() { + $results = array(); + + // Group the rows according to the grouping field, if specified. + $sets = $this->render_grouping($this->view->result, $this->options['grouping']); + + $base_field = $this->view->base_field; + $title_field = $this->display->display_options['content_title_field']; + $title_field_alias = $this->view->field[$title_field]->field_alias; + + // TODO : We don't display grouping info for now. + // Could be useful for select widget, though. + $this->view->row_index = 0; + foreach ($sets as $title => $records) { + foreach ($records as $label => $row) { + $results[$row->{$base_field}] = array( + 'title' => $row->{$title_field_alias}, + 'rendered' => $this->row_plugin->render($row), + ); + $this->view->row_index++; + } + } + unset($this->view->row_index); + return $results; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.info new file mode 100644 index 0000000000000000000000000000000000000000..693101c29355ad93c5fcb3b1444673f802d1f337 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.info @@ -0,0 +1,12 @@ +; $Id$ +name = Content Copy +description = Enables ability to import/export field definitions. +dependencies[] = content +package = CCK +core = 6.x +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.module new file mode 100644 index 0000000000000000000000000000000000000000..d0154705ccaafa30180d1b5832b93d1386000a77 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.module @@ -0,0 +1,649 @@ +<?php +// $Id$ + +/** + * @file + * Adds capability to import/export CCK field data definitions. + * + * Emulates the import/export process introduced in Views to export the field settings arrays as text + * them copy and paste text to import the field settings back into another content type. + * + * Functions to create and playback macros borrowed from moshe weitzman's macro module. + * Macros created using drupal_execute() on the field settings form for each of the requested forms. + * Multi-part forms built using examples from Jeff Eaton's example at + * http://jeff.viapositiva.net/drupal/dynamic-forms. + * + * You can export one or two fields and/or groups from one content type and import them into + * another content type in the same or a different installation, + * or export a complete content type with all groups and fields and create it + * as an exact copy in another installation. + * + * Content type, group and field names will be imported exactly as exported. + * If the names are already in use, no import will be performed. + * + * + * Note: The "display fields" information is being handled a little differently than the rest of the + * data that's imported and exported. Instead of calling through the create and playback macros, + * we get and set the data directly from/into the database. the reason for this is that the + * playback macro method does not lend itself well to the display fields. + */ + +/** + * Implementation of hook_menu(). + */ +function content_copy_menu() { + $items = array(); + + $items['admin/content/types/export'] = array( + 'title' => 'Export', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('content_copy_export_form'), + 'access arguments' => array('administer content types'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 3, + ); + $items['admin/content/types/import'] = array( + 'title' => 'Import', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('content_copy_import_form'), + 'access arguments' => array('administer content types'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 4, + ); + return $items; +} + +/** + * Implementation of hook_theme(). + */ +function content_copy_theme() { + return array( + 'content_copy_export_form' => array( + 'template' => 'content_copy_export_form', + 'arguments' => array('form' => NULL), + ), + ); +} + +/** + * A form to export field definitions. + */ +function content_copy_export_form(&$form_state) { + include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc'); + include_once('./'. drupal_get_path('module', 'node') .'/content_types.inc'); + + $form_values = isset($form_state['values']) ? $form_state['values'] : array(); + $step = isset($form_state['storage']['step']) ? $form_state['storage']['step'] + 1 : 1; + + $exportable_fields = array(); + $groups = array(); + + $type_name = isset($form_values['type_name']) ? $form_values['type_name'] : ''; + if ($type_name) { + $type = content_types($type_name); + $exportable_fields = content_copy_fields($type_name); + if (module_exists('fieldgroup')) { + $groups = fieldgroup_groups($type_name); + } + } + + // If a content type has been selected and there are no fields or groups to select, + // jump straight to export. + if ($step == 2 && !($groups) && !($exportable_fields)) { + $step = 3; + } + + $form['#step'] = $step; + $form['#prefix'] = t('This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to an existing content type or create a new content type that includes the selected fields.'); + + switch ($step) { + case 1: // Select a content type. + $types = content_copy_types(); + $form['type_name'] = array( + '#title' => t('Types'), + '#type' => 'radios', + '#options' => $types, + '#description' => t('Select the content type to export.'), + ); + break; + + case 2: // Select groups and fields. + $form['type_name'] = array( + '#type' => 'hidden', + '#value' => $type_name, + ); + + $form += array( + '#fields' => $exportable_fields, + '#groups' => array_keys($groups), + ); + + $fields_options = $groups_options = array(); + + // Fields. + foreach ($exportable_fields as $field_name) { + $field = content_fields($field_name, $type_name); + $fields_options[$field_name] = ''; + $weight = $field['widget']['weight']; + $form[$field_name] = array( + 'human_name' => array('#value' => check_plain($field['widget']['label'])), + 'field_name' => array('#value' => $field['field_name']), + 'type' => array('#value' => $field['type']), + 'weight' => array('#type' => 'value', '#value' => $weight), + 'parent' => array('#type' => 'value', '#value' => ''), + '#row_type' => 'field', + ); + } + $form['fields'] = array( + '#type' => 'checkboxes', + '#options' => $fields_options, + '#default_value' => array_keys($fields_options), + ); + + // Groups. + foreach ($groups as $name => $group) { + $groups_options[$name] = ''; + $weight = $group['weight']; + $form[$name] = array( + 'human_name' => array('#value' => check_plain($group['label'])), + 'group_name' => array('#value' => $group['group_name']), + 'weight' => array('#type' => 'value', '#value' => $weight), + '#row_type' => 'group', + ); + foreach ($group['fields'] as $field_name => $field) { + // Do nothing for non-exportable (inactive) fields. + if (isset($form[$field_name])) { + $form[$field_name]['parent']['#value'] = $name; + } + } + } + if ($groups) { + $form['groups'] = array( + '#type' => 'checkboxes', + '#options' => $groups_options, + '#default_value' => array_keys($groups_options), + ); + } + break; + + case 3: // Display the export macro. + $GLOBALS['content_copy']['count'] = 0; + $form['export'] = array( + '#title' => t('Export data'), + '#type' => 'textarea', + '#cols' => 60, + '#value' => content_copy_export($form_values), + '#rows' => max(40, $GLOBALS['content_copy']['count']), + '#description' => t('Copy the export text and paste it into another content type using the import function.'), + ); + // The calls to drupal_execute('content_field_edit_form') in + // content_copy_export() affect the page title, + drupal_set_title(t('Content types')); + break; + } + + if ($step < 3) { // Omit submit button on the textarea block to display the export data. + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Export'), + ); + } + + $form['step'] = array( + '#type' => 'value', + '#value' => $step, + ); + + return $form; +} + +function content_copy_export_form_submit($form, &$form_state) { + $form_state['rebuild'] = TRUE; + $form_state['storage']['step'] = $form_state['values']['step']; +} + + +/** + * Process the export, get field admin forms for all requested fields + * and save the form values as formatted text. + */ +function content_copy_export($form_values) { + // Set a global variable to tell when to intervene with form_alter(). + $GLOBALS['content_copy']['status'] = 'export'; + + // Get the content type info by submitting the content type form. + $node_state = array('values' => array('type_name' => $form_values['type_name'])); + module_load_include('inc', 'node', 'content_types'); + drupal_execute('node_type_form', $node_state, node_get_types('type', $form_values['type_name'])); + + module_load_include('inc', 'content', 'includes/content.admin'); + module_load_include('inc', 'content', 'includes/content.crud'); + + // Get an array of groups to export. + // Record a macro for each group by submitting the group edit form. + $groups = array(); + if (!empty($form_values['groups']) && module_exists('fieldgroup')) { + $groups = array_filter($form_values['groups']); + foreach ($groups as $group) { + $group_state = array('values' => array('group_name' => $group)); + drupal_execute('fieldgroup_group_edit_form', $group_state, $form_values['type_name'], $group, 'edit'); + } + } + + // Get an array of fields to export + // Record a macro for each field by submitting the field settings form. + // Omit fields from the export if their module is not currently installed + // otherwise the system will generate errors when the macro tries to execute their forms. + if (!empty($form_values['fields'])) { + $type = content_types($form_values['type_name']); + $fields = array_filter($form_values['fields']); + foreach ($fields as $field_name) { + $field = $type['fields'][$field_name]; + $field_types = _content_field_types(); + $field_module = $field_types[$field['type']]['module']; + $widget_types = _content_widget_types(); + $widget_module = $widget_types[$field['widget']['type']]['module']; + if (!empty($field_module) && module_exists($field_module) && !empty($widget_module) && module_exists($widget_module)) { + $field_state = array('values' => content_field_instance_collapse($field)); + $field_state['values']['op'] = t('Save field settings'); + if (module_exists('fieldgroup')) { + // Avoid undefined index error by always creating this. + $field_state['values']['group'] = ''; + $group_name = fieldgroup_get_group($form_values['type_name'], $field_name); + if (in_array($group_name, $groups)) { + $field_state['values']['group'] = $group_name; + } + } + drupal_execute('content_field_edit_form', $field_state, $form_values['type_name'], $field_name); + } + } + } + + // Convert the macro array into formatted text. + $output = content_copy_get_macro(); + + // Add weights of non-CCK fields. + if ($extra = variable_get('content_extra_weights_'. $form_values['type_name'], array())) { + $output .= "\$content['extra'] = ". var_export((array) $extra, TRUE) .";\n"; + } + + return $output; +} + +/** + * A form to import formatted text created with export. + * + * The macro can be filled from a file, if provided. + * Provide a type_name to force the fields to be added to a specific + * type, or leave out type_name to create a new content type. + * + * Example: + * // If Content Copy is enabled, offer an import link. + * if (module_exists('content_copy')) { + * $form['macro'] = array( + * '#type' => 'fieldset', + * '#title' => t('Create a content type'), + * '#description' => t('Follow this link to create automatically a content type and import preconfigured fields.'), + * '#collapsible' => TRUE, + * '#collapsed' => FALSE, + * ); + * $form['macro']['link'] = array( + * '#type' => 'markup', + * '#value' => l(t('import'), 'admin/content/types/import', array(), 'type_name=event¯o_file='. drupal_get_path('module', 'my_module') .'/my_content_type.txt'), + * ); + * } + */ +function content_copy_import_form(&$form_state, $type_name = '') { + include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc'); + include_once('./'. drupal_get_path('module', 'node') .'/content_types.inc'); + + $form['#prefix'] = t('This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type.'); + $form['type_name'] = array( + '#type' => 'select', + '#options' => array('<create>' => t('<Create>')) + content_copy_types(), + '#default_value' => $type_name, + '#title' => t('Content type'), + '#description' => t('Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields.'), + ); + $form['macro'] = array( + '#type' => 'textarea', + '#rows' => 40, + '#title' => t('Import data'), + '#required' => TRUE, + '#description' => t('Paste the text created by a content export into this field.'), + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Import'), + ); + // Read in a file if there is one and set it as the default macro value. + if (isset($_REQUEST['macro_file']) && $file = file_get_contents($_REQUEST['macro_file'])) { + $form['macro']['#default_value'] = $file; + if (isset($_REQUEST['type_name'])) { + $form['type_name']['#default_value'] = $_REQUEST['type_name']; + } + $form['#prefix'] .= '<p class="error">'. t('A file has been pre-loaded for import.') .'</p>'; + } + return $form; +} + +/** + * Submit handler for import form. + * For each submitted field: + * 1) add new field to the database + * 2) execute the imported field macro to update the settings to the imported values + */ +function content_copy_import_form_submit($form, &$form_state) { + $form_values = $form_state['values']; + + // Get the content type we are importing into. + $type_name = $form_values['type_name']; + $type_label = node_get_types('name', $type_name); + + $content = NULL; + // Convert the import formatted text back into a $content array. + // Return if errors generated or not an array. + // Use '@' to suppress errors about undefined constants in the macro. + @eval($form_values['macro']); + + // Preliminary error trapping, must have valid arrays to work with. + if (!isset($content) || !isset($content['type']) || !is_array($content) || !is_array($content['type'])) { + form_set_error('macro', t('The import data is not valid import text.')); + return; + } + + module_load_include('inc', 'content', 'includes/content.crud'); + + // Get all type and field info for this database. + $content_info = _content_type_info(); + + $imported_type = $content['type']; + $imported_type_name = $imported_type['type']; + $imported_type_label = $imported_type['name']; + + // It is allowed to import a type with no fields, + // so the fields array could be empty and must be cast as an array. + $imported_fields = isset($content['fields']) ? $content['fields'] : array(); + + // Perform more pre-import error trapping. + // If there are potential problems, exit without doing the import. + $not_enabled = array(); + + // The groups array could be empty and still valid, make sure to cast it as an array. + // If there are groups in the import, make sure the fieldgroup module is enabled. + $imported_groups = array(); + if (isset($content['groups']) && module_exists('fieldgroup')) { + $imported_groups = (array) $content['groups']; + } + elseif (isset($content['groups']) && is_array($content['groups'])) { + $not_enabled[] = 'fieldgroup'; + } + + // Make sure that all the field and widget modules in the import are enabled in this database. + foreach ($imported_fields as $import) { + $field = content_field_instance_collapse($import); + if (empty($field['module']) || empty($field['widget_module'])) { + $not_enabled[] = $field['field_name']; + } + else { + if (!module_exists($field['module'])) { + $not_enabled[] = $field['module']; + } + if (!module_exists($field['widget_module'])) { + $not_enabled[] = $field['widget_module']; + } + } + } + + // If any required module is not enabled, set an error message and exit. + if ($not_enabled) { + form_set_error('macro', t('The following modules must be enabled for this import to work: %modules.', array( + '%modules' => implode(', ', array_unique($not_enabled)) + ))); + } + + // Make sure the imported content type doesn't already exist in the database. + if ($form_values['type_name'] == '<create>') { + if (in_array($imported_type_name, array_keys($content_info['content types']))) { + form_set_error('macro', t('The content type %type already exists in this database.', array( + '%type' => $imported_type_name + ))); + } + } + + if (form_get_errors()) { + drupal_set_message(t('Exiting. No import performed.'), 'error'); + return; + } + + // Create the content type, if requested. + if ($form_values['type_name'] == '<create>') { + + $type = (object) $imported_type; + $values = $imported_type; + // Prevent a warning in node/content_types.inc + $type->has_title = TRUE; + $type_form_state = array('values' => $values); + + // There's no API for creating node types, we still have to use drupal_execute(). + drupal_execute('node_type_form', $type_form_state, $type); + + // Reset type and database values once new type has been added. + $type_name = $imported_type_name; + $type_label = node_get_types('name', $type_name); + content_clear_type_cache(); + $content_info = _content_type_info(); + + if (form_get_errors() || !isset($content_info['content types']) || !is_array($content_info['content types'][$type_name])) { + drupal_set_message(t('An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details.', array( + '%type' => $imported_type_name + ))); + return; + } + } + + // Create the groups for this type, if they don't already exist. + if (module_exists('fieldgroup') && $imported_groups) { + foreach ($imported_groups as $group) { + $group_name = $group['group_name']; + fieldgroup_save_group($type_name, $group); + } + // Reset the static variable in fieldgroup_groups() with new data. + fieldgroup_groups('', FALSE, TRUE); + } + + // Iterate through the field forms in the import and execute each. + $rebuild = FALSE; + foreach ($imported_fields as $field) { + + // Make sure the field doesn't already exist in the type. + // If so, do nothing, fields can't be duplicated within a content type. + $field_name = $field['field_name']; + + // Might need to overwrite the content type name if a new type was created. + $field['type_name'] = $type_name; + + if (!empty($field['field_name']) && isset($content_info['content types'][$type_name]['fields'][$field_name])) { + drupal_set_message(t('The imported field %field_label (%field_name) was not added to %type because that field already exists in %type.', array( + '%field_label' => $field['label'], '%field_name' => $field_name, '%type' => $type_label))); + } + else { + $field = content_field_instance_create($field, FALSE); + $rebuild = TRUE; + drupal_set_message(t('The field %field_label (%field_name) was added to the content type %type.', array( + '%field_label' => $field['widget']['label'], '%field_name' => $field_name, '%type' => $type_label))); + } + + // Fieldgroup module erases all group related data when a module that + // provides a content type is disabled, but CCK does not remove the fields. + // In this case, we should ensure group data related to fields is properly + // restored. Hence, we need to update field group data for newly imported + // field, but also for fields that already exist. + if (module_exists('fieldgroup') && isset($imported_groups)) { + fieldgroup_update_fields($field); + } + } + + // Clear caches and rebuild menu only if any field has been created. + if ($rebuild) { + content_clear_type_cache(TRUE); + menu_rebuild(); + } + + // Import weights of non-CCK fields. + if (isset($content['extra'])) { + variable_set('content_extra_weights_'. $type_name, $content['extra']); + } +} + +/** + * Implementation of hook_form_alter(). + * Intervene to run form through macro when doing export + */ +function content_copy_form_alter(&$form, $form_state, $form_id) { + $alter_forms = array('node_type_form', 'content_field_edit_form', 'fieldgroup_group_edit_form'); + if (isset($GLOBALS['content_copy']) && isset($GLOBALS['content_copy']['status']) && $GLOBALS['content_copy']['status'] == 'export' && in_array($form_id, $alter_forms)) { + $form['#submit'][] = 'content_copy_record_macro'; + } +} + +/** + * Get all the *active* fields for a content type. + */ +function content_copy_fields($type_name) { + $fields = array(); + if (!$type_name) { + return $fields; + } + $content_info = _content_type_info(); + foreach ($content_info['content types'][$type_name]['fields'] as $field_name => $field) { + // Omit fields from the export if their module is not currently installed + // otherwise the system will generate errors when the macro tries to execute their forms. + $field_types = _content_field_types(); + $field_module = $field_types[$field['type']]['module']; + $widget_types = _content_widget_types(); + $widget_module = $widget_types[$field['widget']['type']]['module']; + + if (!$field['locked'] && !empty($field_module) && module_exists($field_module) && !empty($widget_module) && module_exists($widget_module)) { + $fields[] = $field_name; + } + } + return $fields; +} + +/** + * Get all content types. + */ +function content_copy_types() { + $types = array(); + $content_info = _content_type_info(); + foreach ($content_info['content types'] as $type_name => $val) { + $types[$type_name] = check_plain($val['name']) .' ('. $type_name .')'; + } + return $types; +} + +/** + * A handler that stores the form submissions into a $GLOBALS array + */ +function content_copy_record_macro($form, &$form_state) { + $edit = $form_state['values']; + $subs = isset($GLOBALS['content_copy']['submissions']) ? $GLOBALS['content_copy']['submissions'] : array(); + + // Get the form values and store them in a $GLOBALS['content_copy']['submissions'] array. + // Update $GLOBALS['content_copy']['count'] with an approximation of the number of rows in this item. + // Count is used to approximate necessary size of textarea in form. + + $form_id = $form_state['values']['form_id']; + if (isset($edit['type_name']) || isset($edit['submit']) || isset($edit['delete']) || isset($edit['form_id'])) { + unset($edit['type_name'], $edit['submit'], $edit['delete'], $edit['form_id'], $edit['previous_field']); + } + switch ($form_id) { + case 'node_type_form': + $subs['type'] = $edit; + $GLOBALS['content_copy']['count'] += sizeof($edit) + 5; + break; + + case 'fieldgroup_group_edit_form': + $subs['groups'][] = $edit; + $GLOBALS['content_copy']['count'] += sizeof($edit) + 5; + break; + + default: + if (isset($edit['field_widget_type'])) { + $tmp = explode('-', $edit['field_widget_type']); + $field_name = $tmp[0]; + } + else { + $field_name = isset($edit['field_name']) ? $edit['field_name'] : ''; + } + + // The display settings are being fetched directly from the DB. During import, + // we'll re-insert the data directly as well. + // + $query = 'SELECT display_settings FROM {'. content_instance_tablename() .'} WHERE field_name = \'%s\''; + $row_info = db_fetch_array(db_query($query, $field_name)); + + // If an error occurs, notify the user. + if ($db_err = db_error()) { + drupal_set_message(t("An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'.", array( + '%field_name' => $field_name, + '%db_err' => $db_err + ))); + } + else { + // The db fetch occurred successfully, unserialize the data blob and + // insert it into a new "display_settings" field of the data. + if ($display_settings = unserialize($row_info['display_settings'])) { + $edit['display_settings'] = $display_settings; + } + } + $subs['fields'][] = $edit; + $GLOBALS['content_copy']['count'] += sizeof($edit) + 5; + break; + } + + $GLOBALS['content_copy']['submissions'] = $subs; +} + +/** + * @return a code representation of the recorded macro. + */ +function content_copy_get_macro() { + // Define the indexes for the evaluated code. + $string = ""; + if (array_key_exists('submissions', $GLOBALS['content_copy'])) { + foreach ($GLOBALS['content_copy']['submissions'] as $form_type => $form) { + $string .= "\$content['$form_type'] = ". var_export((array) $form, TRUE) .";\n"; + } + return $string; + } +} + +function template_preprocess_content_copy_export_form($vars) { + $form = &$vars['form']; + + if ($form['#step'] == 2) { + $order = _content_overview_order($form, $form['#fields'], $form['#groups']); + + $rows = array(); + foreach ($order as $key) { + $element = &$form[$key]; + $row = new stdClass(); + + $row->row_type = $element['#row_type']; + $checkbox_key = $element['#row_type'] == 'field' ? 'fields' : 'groups'; + $row->checkbox = drupal_render($form[$checkbox_key][$key]); + foreach (element_children($element) as $child) { + $row->{$child} = drupal_render($element[$child]); + } + $row->label_class = in_array($key, $form['#groups']) ? 'label-group' : 'label-field'; + $row->indentation = theme('indentation', isset($element['#depth']) ? $element['#depth'] : 0); + + $rows[] = $row; + } + $vars['rows'] = $rows; + } + + $vars['submit'] = drupal_render($form); +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy_export_form.tpl.php b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy_export_form.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..54b0de6c6196d032969084215098d3aedd152f46 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy_export_form.tpl.php @@ -0,0 +1,42 @@ +<?php +// $Id$ + +if ($form['#step'] == 2): + if ($rows): ?> + <table id="content-copy-export" class="sticky-enabled"> + <thead> + <tr> + <th><?php print t('Export'); ?></th> + <th><?php print t('Label'); ?></th> + <th><?php print t('Name'); ?></th> + <th><?php print t('Type'); ?></th> + </tr> + </thead> + <tbody> + <?php + $count = 0; + foreach ($rows as $row): ?> + <tr class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?>"> + <?php + switch ($row->row_type): + case 'field': ?> + <td><?php print $row->checkbox; ?></td> + <td><?php print $row->indentation; ?><span class="<?php print $row->label_class; ?>"><?php print $row->human_name; ?></span></td> + <td><?php print $row->field_name; ?></td> + <td><?php print $row->type; ?></td> + <?php break; + case 'group': ?> + <td><?php print $row->checkbox; ?></td> + <td><?php print $row->indentation; ?><span class="<?php print $row->label_class; ?>"><?php print $row->human_name; ?></span></td> + <td colspan="2"><?php print $row->group_name; ?></td> + <?php break; + endswitch; ?> + </tr> + <?php $count++; + endforeach; ?> + </tbody> + </table> + <?php endif; + endif; +print $submit; ?> + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.de.po new file mode 100644 index 0000000000000000000000000000000000000000..fd1917e8817ba5cb01106829c1c3f10d017ca94c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.de.po @@ -0,0 +1,137 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2008-11-05 12:54+0100\n" +"PO-Revision-Date: 2008-11-05 13:17+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/content_copy/content_copy_export_form.tpl.php:9 +#: modules/content_copy/content_copy.module:187;38 +msgid "Export" +msgstr "Exportieren" + +#: modules/content_copy/content_copy.module:97 +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "Dieses Formular verarbeitet einen Inhaltstyp, ein oder mehrere Felder von diesem Typ und exportiert die Einstellungen. Der von diesem Prozess erstellte Export kann kopiert und als Import in die Aktuelle oder jede andere Datenbank eingefügt werden. Der Import wird die Felder zu einem vorhandenen Inhaltstyp hinzufügen oder einen neuen Inhaltstyp mit den ausgewählten Feldern erstellen." + +#: modules/content_copy/content_copy.module:103 +msgid "Types" +msgstr "Typen" + +#: modules/content_copy/content_copy.module:107 +msgid "Select the content type to export." +msgstr "Wählen Sie einen Inhaltstyp für den Export." + +#: modules/content_copy/content_copy.module:171 +msgid "Export data" +msgstr "Daten exportieren" + +#: modules/content_copy/content_copy.module:176 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Kopieren Sie den exportierten Text und fügen Sie ihn mit der Importfunktion in einen anderen Inhaltstyp ein." + +#: modules/content_copy/content_copy.module:180 +msgid "Content types" +msgstr "Inhaltstypen" + +#: modules/content_copy/content_copy.module:299 +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "Dieses Formular wird Felddefinitionen importieren, die von einem anderen Inhaltstyp oder anderen Datenbank exportiert wurden.<br />Dabei ist zu beachten, dass die Felder nicht innerhalb des gleichen Inhalttyps dupliziert werden können, deshalb werden importierte Felder nur hinzugefügt, wenn diese im ausgewählten Typ noch nicht vorhanden sind." + +#: modules/content_copy/content_copy.module:302 +msgid "<Create>" +msgstr "<Erstellen>" + +#: modules/content_copy/content_copy.module:304 +msgid "Content type" +msgstr "Inhaltstyp" + +#: modules/content_copy/content_copy.module:305 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Wählen Sie den Inhaltstyp zum Aufnehmen der importierten Felder aus.<br/>Wählen Sie <Erstellen> zum Erstellen eines neuen Inhaltstyps für die zu importierenden Felder." + +#: modules/content_copy/content_copy.module:310 +msgid "Import data" +msgstr "Daten importieren" + +#: modules/content_copy/content_copy.module:312 +msgid "Paste the text created by a content export into this field." +msgstr "Fügen Sie den Text aus einem Inhaltsexport in dieses Feld ein." + +#: modules/content_copy/content_copy.module:316;46 +msgid "Import" +msgstr "Importieren" + +# "vorgeladen" sounds strange +#: modules/content_copy/content_copy.module:324 +#, fuzzy +msgid "A file has been pre-loaded for import." +msgstr "Eine Datei wurde für den Import vorgeladen." + +#: modules/content_copy/content_copy.module:350 +msgid "The import data is not valid import text." +msgstr "Die importierten Daten sind kein gültiger Importtext." + +#: modules/content_copy/content_copy.module:399 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "Die folgenden Module müssen eingeschaltet sein, damit dieser Import erfolgreich durchgeführt werden kann: %modules." + +#: modules/content_copy/content_copy.module:407 +msgid "The content type %type already exists in this database." +msgstr "Der Inhaltstyp %type existiert bereits in dieser Datenbank." + +#: modules/content_copy/content_copy.module:414 +msgid "Exiting. No import performed." +msgstr "Abbruch. Kein Import durchgeführt." + +#: modules/content_copy/content_copy.module:438 +msgid "An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Beim Hinzufügen des Inhaltstyps %type trat ein Fehler auf.<br/>Bitte überprüfen Sie die angezeigten Fehler für weitere Details." + +#: modules/content_copy/content_copy.module:463 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "Das importierte Feld %field_label (%field_name) wurde nicht zu %type hinzugefügt, weil dieses Feld bereits in %type existiert." + +#: modules/content_copy/content_copy.module:472 +msgid "The field %field_label (%field_name) was added to the content type %type." +msgstr "Das Feld %field_label (%field_name) wurde zu dem Inhaltstyp %type hinzugefügt." + +#: modules/content_copy/content_copy.module:553 +msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'." +msgstr "Beim Exportieren der ‚Anzeige-Einstellungs‘-Daten für das Feld %field_name ist ein Fehler aufgetreten.<br />Der DB-Fehler ist: ‚%db_err‘." + +#: modules/content_copy/content_copy.module:0 +msgid "content_copy" +msgstr "Inhaltskopie" + +#: modules/content_copy/content_copy.info:0 +msgid "Content Copy" +msgstr "Inhaltskopie" + +#: modules/content_copy/content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "Aktiviert die Möglichkeit zum Importieren und Exportieren von Felddefinitionen." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..6c54ab5d2dc5834a2126d6dc2afa833887247644 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.fr.po @@ -0,0 +1,177 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 13:52+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: modules/content_copy/content_copy.module:80 +msgid "" +"This form will process a content type and one or more fields from that type " +"and export the settings. The export created by this process can be copied " +"and pasted as an import into the current or any other database. The import " +"will add the fields to into an existing content type or create a new content " +"type that includes the selected fields." +msgstr "" +"Ce formulaire traitera un type de contenu et un ou plusieurs champs de ce " +"type, pour en exporter les paramètres. Le code d'export ainsi généré peut " +"être copié et collé dans la page d'import, vers la base de données courante " +"ou vers une autre base de données. L'opération d'import ajoutera les champs " +"à un type de contenu existant ou créera un nouveau type de contenu intégrant " +"les champs sélectionnés." + +#: modules/content_copy/content_copy.module:86 +msgid "Types" +msgstr "Types" + +#: modules/content_copy/content_copy.module:90 +msgid "Select the content type to export." +msgstr "Sélectionner le type de contenu à exporter." + +#: modules/content_copy/content_copy.module:115 +msgid "Groups" +msgstr "Groupes" + +#: modules/content_copy/content_copy.module:119 +msgid "Select the group definitions to export from %type." +msgstr "Sélectionnez les définitions de groupes à exporter depuis '%type'." + +#: modules/content_copy/content_copy.module:129 +msgid "Select the field definitions to export from %type." +msgstr "Sélectionnez les définitions de champs à exporter depuis '%type'." + +#: modules/content_copy/content_copy.module:139 +msgid "Export data" +msgstr "Données exportée" + +#: modules/content_copy/content_copy.module:144 +msgid "" +"Copy the export text and paste it into another content type using the import " +"function." +msgstr "" +"Copiez le texte exporté et collez-le dans le type de contenu de votre choix, " +"à l'aide de la fonction d'import." + +#: modules/content_copy/content_copy.module:154;38 +msgid "Export" +msgstr "Exporter" + +#: modules/content_copy/content_copy.module:227 +msgid "" +"This form will import field definitions exported from another content type " +"or another database.<br/>Note that fields cannot be duplicated within the " +"same content type, so imported fields will be added only if they do not " +"already exist in the selected type." +msgstr "" +"Ce formulaire permet d'importer les définitions de champs exportées depuis " +"un autre type de contenu ou depuis une autre base de données.<br/>Notez que " +"les champs ne peuvent être dupliqués au sein d'un même type de contenu : les " +"champs importés ne peuvent donc être ajoutés que s'ils n'existent pas encore " +"dans le type sélectionné." + +#: modules/content_copy/content_copy.module:230 +msgid "<Create>" +msgstr "<Créer>" + +#: modules/content_copy/content_copy.module:232 +msgid "Content type" +msgstr "Type de contenu" + +#: modules/content_copy/content_copy.module:233 +msgid "" +"Select the content type to import these fields into.<br/>Select <" +"Create> to create a new content type to contain the fields." +msgstr "" +"Choisissez le type de contenu vers lequel vous voulez importer ces champs." +"<br/>Sélectionnez <Create> pour créer un nouveau type de contenu " +"comportant ces champs." + +#: modules/content_copy/content_copy.module:238 +msgid "Import data" +msgstr "Données à importer" + +#: modules/content_copy/content_copy.module:240 +msgid "Paste the text created by a content export into this field." +msgstr "Collez dans ce champ le texte créé par un export de contenu." + +#: modules/content_copy/content_copy.module:244;46 +msgid "Import" +msgstr "Importer" + +#: modules/content_copy/content_copy.module:270 +msgid "The import data is not valid import text." +msgstr "Les données d'import ne sont valides." + +#: modules/content_copy/content_copy.module:318 +msgid "" +"The following modules must be enabled for this import to work: %modules." +msgstr "" +"Les modules suivants doivent être activés pour que l'import fonctionne : '%" +"modules'." + +#: modules/content_copy/content_copy.module:324;338 +msgid "<create>" +msgstr "<créer>" + +#: modules/content_copy/content_copy.module:326 +msgid "The content type %type already exists in this database." +msgstr "Le type de contenu '%type' existe déjà dans cette base de données." + +#: modules/content_copy/content_copy.module:333 +msgid "Exiting. No import performed." +msgstr "Abandon. L'import n'a pas été réalisé." + +#: modules/content_copy/content_copy.module:355 +msgid "" +"An error has occurred adding the content type %type.<br/>Please check the " +"errors displayed for more details." +msgstr "" +"Une erreur s'est produite à l'ajout du type de contenu '%type'.<br/" +">Consultez les erreurs affichées à l'écran pour plus de détails." + +#: modules/content_copy/content_copy.module:380 +msgid "" +"The imported field %field_label (%field_name) was not added to %type because " +"that field already exists in %type." +msgstr "" +"Le champ importé '%field_label' (%field_name) n'a pas été ajouté à '%type' " +"car ce champ existe déjà." + +#: modules/content_copy/content_copy.module:389 +msgid "" +"The field %field_label (%field_name) was added to the content type %type." +msgstr "" +"Le champ importé '%field_label' (%field_name) a été ajouté au type de " +"contenu '%type'." + +#: modules/content_copy/content_copy.module:503 +msgid "" +"An error occurred when exporting the 'display settings' data for the field %" +"field_name.<br/>The db error is: '%db_err'." +msgstr "" +"Une erreur s'est produite à l'export des données 'paramètres d'affichage' " +"pour le champ '%field_name'.<br/>L'erreur renvoyée par la base de données " +"est : '%db_err'." + +#: modules/content_copy/content_copy.module:0 +msgid "content_copy" +msgstr "content_copy" + +#: modules/content_copy/content_copy.info:0 +msgid "Content Copy" +msgstr "Content Copy" + +#: modules/content_copy/content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "Permet d'importer et d'exporter des définitions de champs." diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..12c9d4acba998013d30ecc6d21502d411cc27257 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.hu.po @@ -0,0 +1,193 @@ +# Hungarian translation of cck (6.x-2.0-rc10) +# Copyright (c) 2008 by the Hungarian translation team +# Generated from files: +# content_copy.module,v 1.27.2.13 2008/10/08 12:55:54 karens +# content_copy.info,v 1.6 2008/04/23 18:01:48 dww +# +msgid "" +msgstr "" +"Project-Id-Version: cck (6.x-2.0-rc10)\n" +"POT-Creation-Date: 2008-10-31 12:16-0500\n" +"PO-Revision-Date: 2008-10-26 11:48-0500\n" +"Last-Translator: Balogh Zoltán\n" +"Language-Team: Drupal.hu Fordítói Csapat <forditas [at] drupal.hu>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: modules/content_copy/content_copy.module:262,46 +msgid "Import" +msgstr "Import" + +#: modules/content_copy/content_copy.module:139,38 +msgid "Export" +msgstr "Export" + +#: modules/content_copy/content_copy.module:132 +msgid "Content types" +msgstr "Tartalom típusok" + +#: modules/content_copy/content_copy.module:100 +msgid "Groups" +msgstr "Csoportok" + +#: modules/content_copy/content_copy.module:250 +msgid "Content type" +msgstr "Tartalomtípus" + +#: modules/content_copy/content_copy.module:85 +msgid "Types" +msgstr "Típusok" + +#: modules/content_copy/content_copy.module:80 +msgid "" +"This form will process a content type and one or more fields from that " +"type and export the settings. The export created by this process can " +"be copied and pasted as an import into the current or any other " +"database. The import will add the fields to into an existing content " +"type or create a new content type that includes the selected fields." +msgstr "" +"Ez az űrlap készíti el a tartalomtípus és a típusból egy vagy " +"több mező beállításainak exportálását. A folyamat által " +"készített exportot lehet lemásolni és mint importot beilleszteni " +"az aktuális, vagy bármely más adatbázisba. Az import hozzá fogja " +"adni a mezőket egy létező tartalom típushoz, vagy létre fog hozni " +"egy új tartalomtípust, mely tartalmazni fogja a kiválasztott " +"mezőket." + +#: modules/content_copy/content_copy.module:89 +msgid "Select the content type to export." +msgstr "Tartalomtípus kiválasztása az exporthoz." + +#: modules/content_copy/content_copy.module:104 +msgid "Select the group definitions to export from %type." +msgstr "" +"Csoport meghatározások kiválasztása az exporthoz a következő " +"tartalomtípusból: %type." + +#: modules/content_copy/content_copy.module:114 +msgid "Select the field definitions to export from %type." +msgstr "" +"Mező meghatározások kiválasztása az exporthoz a következő " +"tartalom típusból: %type." + +#: modules/content_copy/content_copy.module:123 +msgid "Export data" +msgstr "Adatok exportálása" + +#: modules/content_copy/content_copy.module:128 +msgid "" +"Copy the export text and paste it into another content type using the " +"import function." +msgstr "" +"Az export által előállított szöveget át lehet másolni egy " +"másik tartalomtípusba az import művelet segítségével." + +#: modules/content_copy/content_copy.module:245 +msgid "" +"This form will import field definitions exported from another content " +"type or another database.<br/>Note that fields cannot be duplicated " +"within the same content type, so imported fields will be added only if " +"they do not already exist in the selected type." +msgstr "" +"Ez az űrlap importálja a mező meghatározásokat, melyek egy másik " +"tartalom típusból, vagy egy másik adatbázisból lettek " +"exportálva.<br/>Megjegyzés: Egy tartalom típuson belül a mezőket " +"nem lehet többszörözni, így csak azok a mezők lesznek hozzáadva, " +"melyek még nem szerepelnek a kiválasztott tartalom típusban." + +#: modules/content_copy/content_copy.module:248 +msgid "<Create>" +msgstr "<Létrehozás>" + +#: modules/content_copy/content_copy.module:251 +msgid "" +"Select the content type to import these fields into.<br/>Select " +"<Create> to create a new content type to contain the fields." +msgstr "" +"Tartalom típus kiválasztása a mezők importálásához.<br/>A " +"<Létrehozás> segítségével új tartalom típus jön létre, " +"mely tartalmazni fogja a mezőket." + +#: modules/content_copy/content_copy.module:256 +msgid "Import data" +msgstr "Adatok importálása" + +#: modules/content_copy/content_copy.module:258 +msgid "Paste the text created by a content export into this field." +msgstr "" +"A tartalom exportnál keletkezett szöveget kell ebbe a mezőbe " +"illeszteni." + +#: modules/content_copy/content_copy.module:270 +msgid "A file has been pre-loaded for import." +msgstr "A fájl előzetesen be lett töltve az importhoz." + +#: modules/content_copy/content_copy.module:296 +msgid "The import data is not valid import text." +msgstr "Az adat nem értelmezhető import szövegként." + +#: modules/content_copy/content_copy.module:344 +msgid "" +"The following modules must be enabled for this import to work: " +"%modules." +msgstr "" +"A következő modulokat engedélyezni kell, hogy ez az import " +"működjön: %modules." + +#: modules/content_copy/content_copy.module:352 +msgid "The content type %type already exists in this database." +msgstr "%type tartalomtípus már szerepel az adatbázisban." + +#: modules/content_copy/content_copy.module:359 +msgid "Exiting. No import performed." +msgstr "Kilépés. Az importálás nem lett végrehajtva." + +#: modules/content_copy/content_copy.module:383 +msgid "" +"An error has occurred adding the content type %type.<br/>Please check " +"the errors displayed for more details." +msgstr "" +"Hiba történt a következő tartalomtípus hozzáadása közben: " +"%type.<br />További részletek a megjelenített hibaüzenetekben." + +#: modules/content_copy/content_copy.module:409 +msgid "" +"The imported field %field_label (%field_name) was not added to %type " +"because that field already exists in %type." +msgstr "" +"%field_label (%field_name) mező már létezik, ezért az import " +"során nem lett hozzáadva a következő tartalomtípushoz: %type." + +#: modules/content_copy/content_copy.module:418 +msgid "" +"The field %field_label (%field_name) was added to the content type " +"%type." +msgstr "" +"%field_label (%field_name) mező hozzá lett adva a következő " +"tartalomtípushoz: %type." + +#: modules/content_copy/content_copy.module:532 +msgid "" +"An error occurred when exporting the 'display settings' data for the " +"field %field_name.<br/>The db error is: '%db_err'." +msgstr "" +"%field_name mező „Megjelenítési beállítás” adatainak " +"exportálása közben egy hiba keletkezett. <br />Az adatbázis hiba: " +"„%db_err”." + +#: modules/content_copy/content_copy.module:0 +msgid "content_copy" +msgstr "content_copy" + +#: modules/content_copy/content_copy.info:0 +msgid "Content Copy" +msgstr "Content Copy" + +#: modules/content_copy/content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "" +"Lehetővé teszi a meződefiníciók importálását és " +"exportálását." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.nl.po new file mode 100644 index 0000000000000000000000000000000000000000..4ae43085f7770d9ff452a3578cf1f68ab4468fdb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.nl.po @@ -0,0 +1,146 @@ +# $Id$ +# +# Dutch translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched +# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched +# content_copy.info,v 1.6 2008/04/23 18:01:48 dww +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-03 14:25+0200\n" +"PO-Revision-Date: 2009-06-03 14:27+0100\n" +"Last-Translator: L.B. Cohn <lichai@999games.nl>\n" +"Language-Team: Dutch <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: content_copy_export_form.tpl.php:9 +#: content_copy.module:191;38 +msgid "Export" +msgstr "Exporteren" + +#: content_copy_export_form.tpl.php:10 +msgid "Label" +msgstr "Label" + +#: content_copy_export_form.tpl.php:11 +msgid "Name" +msgstr "Naam" + +#: content_copy_export_form.tpl.php:12 +msgid "Type" +msgstr "Type" + +#: content_copy.module:97 +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "Dit formulier zal een inhoudstype en één of meerdere velden van dat type exporteren. Dit kan worden gekopieerd en geplakt in deze of een andere database. Importeren zal deze velden aan een bestanden inhoudstype toevoegen of een nieuw inhoudstype maken met de geselecteerde velden." + +#: content_copy.module:103 +msgid "Types" +msgstr "Typen" + +#: content_copy.module:107 +msgid "Select the content type to export." +msgstr "Selecteer de inhoudstypes om te exporteren" + +#: content_copy.module:175 +msgid "Export data" +msgstr "Exporteer data" + +#: content_copy.module:180 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Kopieer de geexporteerde tekst en plak het in een ander inhoudstype of gebruik de importeerfunctie." + +#: content_copy.module:184 +msgid "Content types" +msgstr "Inhoudstypen" + +#: content_copy.module:251 +msgid "Save field settings" +msgstr "Veldinstellingen indienen" + +#: content_copy.module:303 +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "Dit formulier zal veldinformatie importeren die zijn geexporteerd uit een ander inhoudstype of database.<br />Merk op dat velden niet kunnen worden gedupliceerd in hetzelfde inhoudstype, dus geimporteerde velden zullen alleen worden toegevoegd als ze nog niet bestaan in het geselecteerde inhoudstype." + +#: content_copy.module:306 +msgid "<Create>" +msgstr "<Maak>" + +#: content_copy.module:308 +msgid "Content type" +msgstr "Inhoudstype" + +#: content_copy.module:309 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Selecteer het inhoudstype waarin deze velden moeten worden geimporteerd.<br />Selecteer <Maak> om een nieuw inhoudstype te maken waarin de velden komen." + +#: content_copy.module:314 +msgid "Import data" +msgstr "Importeer data" + +#: content_copy.module:316 +msgid "Paste the text created by a content export into this field." +msgstr "Plak de tekst die is geexporteerd in dit veld." + +#: content_copy.module:320;46 +msgid "Import" +msgstr "Importeren" + +#: content_copy.module:328 +msgid "A file has been pre-loaded for import." +msgstr "Een bestand is voorgeladen voor het importeren." + +#: content_copy.module:354 +msgid "The import data is not valid import text." +msgstr "De geimporteerde data is geen valide importeertekst." + +#: content_copy.module:403 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "De volgende modules moeten worden aangezet om te kunnen importeren: %modules." + +#: content_copy.module:411 +msgid "The content type %type already exists in this database." +msgstr "Het inhoudstype %type bestaat al in de database." + +#: content_copy.module:418 +msgid "Exiting. No import performed." +msgstr "Gestopt, er is niks geimporteerd." + +#: content_copy.module:442 +msgid "An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Er is een fout opgetreden tijden het toevoegen van het inhoudstype %type.<br />Bekijk de foutmeldingen voor meer informatie." + +#: content_copy.module:467 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "Het geimporteerde veld %field_label (%field_name) is niet toegevoegd aan %type omdat het veld al bestaat in %type." + +#: content_copy.module:476 +msgid "The field %field_label (%field_name) was added to the content type %type." +msgstr "Het veld %field_label (%field_name) is toegevoegd aan het inhoudstype %type." + +#: content_copy.module:581 +msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'." +msgstr "Er is een fout opgetreden tijdens het exporteren van de weergaveinstellingendata voor het veld %field_name.<br />De databasefoutmelding is: '%db_err'." + +#: content_copy.module:0 +msgid "content_copy" +msgstr "content_copy" + +#: content_copy.info:0 +msgid "Content Copy" +msgstr "Kopieer inhoud" + +#: content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "Laat velddefinities geimporteerd en geexporteerd worden." + +#: content_copy.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.pot new file mode 100644 index 0000000000000000000000000000000000000000..c1c4192b03df2028ab408a4b9678cadb93e64ed7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.pot @@ -0,0 +1,126 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-content_copy) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched +# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched +# content_copy.info,v 1.6 2008/04/23 18:01:48 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/content_copy/content_copy_export_form.tpl.php:9 modules/content_copy/content_copy.module:191;38 +msgid "Export" +msgstr "" + +#: modules/content_copy/content_copy.module:97 +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "" + +#: modules/content_copy/content_copy.module:103 +msgid "Types" +msgstr "" + +#: modules/content_copy/content_copy.module:107 +msgid "Select the content type to export." +msgstr "" + +#: modules/content_copy/content_copy.module:175 +msgid "Export data" +msgstr "" + +#: modules/content_copy/content_copy.module:180 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "" + +#: modules/content_copy/content_copy.module:184 +msgid "Content types" +msgstr "" + +#: modules/content_copy/content_copy.module:303 +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "" + +#: modules/content_copy/content_copy.module:306 +msgid "<Create>" +msgstr "" + +#: modules/content_copy/content_copy.module:308 +msgid "Content type" +msgstr "" + +#: modules/content_copy/content_copy.module:309 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "" + +#: modules/content_copy/content_copy.module:314 +msgid "Import data" +msgstr "" + +#: modules/content_copy/content_copy.module:316 +msgid "Paste the text created by a content export into this field." +msgstr "" + +#: modules/content_copy/content_copy.module:320;46 +msgid "Import" +msgstr "" + +#: modules/content_copy/content_copy.module:328 +msgid "A file has been pre-loaded for import." +msgstr "" + +#: modules/content_copy/content_copy.module:354 +msgid "The import data is not valid import text." +msgstr "" + +#: modules/content_copy/content_copy.module:403 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "" + +#: modules/content_copy/content_copy.module:411 +msgid "The content type %type already exists in this database." +msgstr "" + +#: modules/content_copy/content_copy.module:418 +msgid "Exiting. No import performed." +msgstr "" + +#: modules/content_copy/content_copy.module:442 +msgid "An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "" + +#: modules/content_copy/content_copy.module:467 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "" + +#: modules/content_copy/content_copy.module:476 +msgid "The field %field_label (%field_name) was added to the content type %type." +msgstr "" + +#: modules/content_copy/content_copy.module:581 +msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'." +msgstr "" + +#: modules/content_copy/content_copy.module:0 +msgid "content_copy" +msgstr "" + +#: modules/content_copy/content_copy.info:0 +msgid "Content Copy" +msgstr "" + +#: modules/content_copy/content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..cddae942dc49196902faeb76cde97c5fd2b808ef --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.sv.po @@ -0,0 +1,148 @@ +# $Id$ +# +# Swedish translation of Drupal (content_copy) +# Generated from files: +# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched +# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched +# content_copy.info,v 1.6 2008/04/23 18:01:48 dww +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Content Copy 6.x\n" +"POT-Creation-Date: 2009-05-27 12:42+0200\n" +"PO-Revision-Date: 2009-05-27 13:04+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: content_copy_export_form.tpl.php:9 +#: content_copy.module:191;38 +msgid "Export" +msgstr "Exportera" + +#: content_copy_export_form.tpl.php:10 +msgid "Label" +msgstr "Etikett" + +#: content_copy_export_form.tpl.php:11 +msgid "Name" +msgstr "Namn" + +#: content_copy_export_form.tpl.php:12 +msgid "Type" +msgstr "Typ" + +#: content_copy.module:97 +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "Detta formulär kommer att bearbeta en innehållstyp och ett eller flera fält från den typen och exportera inställningarna. Exporten skapad av denna bearbetning kan kopieras och klistras in som en import till den nuvarande, eller annan databas. Importen kommer att lägga till fält till den existerande innehållstypen eller skapa en ny innehållstyp som inkluderade valda fält." + +#: content_copy.module:103 +msgid "Types" +msgstr "Typer" + +#: content_copy.module:107 +msgid "Select the content type to export." +msgstr "Välj innehållstyp att exportera." + +#: content_copy.module:175 +msgid "Export data" +msgstr "Exportera data" + +#: content_copy.module:180 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Kopiera den exporterade texten och klistra in den till en annan innehållstyp genom att använda funktionen för import." + +#: content_copy.module:184 +msgid "Content types" +msgstr "Innehållstyper" + +#: content_copy.module:251 +msgid "Save field settings" +msgstr "Spara inställningar för fält" + +#: content_copy.module:303 +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "Detta formulär kommer att importera definitioner på fält exporterade från annan innehållstyp eller annan databas.<br />Observera att detta fält inte kan vara en dublett inom samma innehållstp, så importerade fält kommer enbart att läggas till om de inte redan existerar i den valda typen." + +#: content_copy.module:306 +msgid "<Create>" +msgstr "<Skapa>" + +#: content_copy.module:308 +msgid "Content type" +msgstr "Innehållstyp" + +#: content_copy.module:309 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Välj innehållstyp att importera dessa fält till.<br />Välj <Skapa> för att skapa en ny innehållstyp som skall innehålla fälten." + +#: content_copy.module:314 +msgid "Import data" +msgstr "Importera data" + +#: content_copy.module:316 +msgid "Paste the text created by a content export into this field." +msgstr "Klistra in texten skapad av en export av innehåll till detta fält." + +#: content_copy.module:320;46 +msgid "Import" +msgstr "Importera" + +#: content_copy.module:328 +msgid "A file has been pre-loaded for import." +msgstr "En fil har förladdats för import." + +#: content_copy.module:354 +msgid "The import data is not valid import text." +msgstr "Det importerade datat är inte giltig text för import." + +#: content_copy.module:403 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "Följande moduler måste aktiveras för att denna import skall fungera: %modules." + +#: content_copy.module:411 +msgid "The content type %type already exists in this database." +msgstr "Innehållstypen %type finns redan i databasen." + +#: content_copy.module:418 +msgid "Exiting. No import performed." +msgstr "Avslutar. Ingen import genomförd." + +#: content_copy.module:442 +msgid "An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Ett fel inträffade när innehållstypen %type lades till.<br />Var vänlig se de visade felmeddelandena för mer detaljer." + +#: content_copy.module:467 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "Det importerade fältet %field_label (%field_name) lades inte till %type eftersom det fältet redan existerar i %type." + +#: content_copy.module:476 +msgid "The field %field_label (%field_name) was added to the content type %type." +msgstr "Fältet %field_label (%field_name) lades till innehållstypen %type." + +#: content_copy.module:581 +msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'." +msgstr "Ett fel inträffade " + +#: content_copy.module:0 +msgid "content_copy" +msgstr "content_copy" + +#: content_copy.info:0 +msgid "Content Copy" +msgstr "Kopiera innehåll" + +#: content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "Aktiverar förmågan att importera/exportera definitioner av fält." + +#: content_copy.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_multigroup/README.txt b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_multigroup/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b15aaddeeb3b17ce2e9fd0aaa70759b80849de4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_multigroup/README.txt @@ -0,0 +1,4 @@ +; $Id$ + +Ongoing work on the multigroup module has moved to the experimental +CCK 3.0 branch. diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.info new file mode 100644 index 0000000000000000000000000000000000000000..3c0e4d4fea138e276c6bb998927def8d0456fb24 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.info @@ -0,0 +1,12 @@ +; $Id$ +name = Content Permissions +description = Set field-level permissions for CCK fields. +package = CCK +core = 6.x +dependencies[] = content +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.install new file mode 100644 index 0000000000000000000000000000000000000000..a499833c6f29e722937e159cecc92d0f031a21a5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.install @@ -0,0 +1,10 @@ +<?php +// $Id$ + +/** + * @file + * Implementation of hook_install(). + */ +function content_permissions_install() { + drupal_set_message(t('Please <a href="!url">configure your field permissions</a> immediately. All fields are inaccessible by default.', array('!url' => url('admin/user/permissions', array('fragment' => 'content_permissions'))))); +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.module new file mode 100644 index 0000000000000000000000000000000000000000..7c81d5d53a28e0f60d1fac00537d8fd5783baede --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.module @@ -0,0 +1,28 @@ +<?php +// $Id$ + +/** + * Implementation of hook_perm(). + */ +function content_permissions_perm() { + $perms = array(); + foreach (content_fields() as $field) { + $perms[] = 'edit '. $field['field_name']; + $perms[] = 'view '. $field['field_name']; + } + return $perms; +} + +/** + * Implementation of hook_field_access(). + * + * @see content_access(). + */ +function content_permissions_field_access($op, $field, $account, $node = NULL) { + switch ($op) { + case 'view': + case 'edit': + return user_access($op .' '. $field['field_name'], $account); + } + return TRUE; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.de.po new file mode 100644 index 0000000000000000000000000000000000000000..ba962aae5b27c722317c3200b2b4047881286c54 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.de.po @@ -0,0 +1,61 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2008-11-05 12:54+0100\n" +"PO-Revision-Date: 2008-11-05 13:18+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854 +#: modules/content_permissions/content_permissions.module:9 +msgid "edit " +msgstr "" + +# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854 +#: modules/content_permissions/content_permissions.module:9;10 +msgid "field_name" +msgstr "" + +# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854 +#: modules/content_permissions/content_permissions.module:10 +msgid "view " +msgstr "" + +#: modules/content_permissions/content_permissions.module:0 +msgid "content_permissions" +msgstr "Inhaltsberechtigungen" + +#: modules/content_permissions/content_permissions.install:9 +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "Bitte umgehend die <a href=\"!url\">Feldberechtigungen konfigurieren</a>. Alle Felder sind standardmäßig gesperrt." + +#: modules/content_permissions/content_permissions.info:0 +msgid "Content Permissions" +msgstr "Inhaltsberechtigungen" + +#: modules/content_permissions/content_permissions.info:0 +msgid "Set field-level permissions for CCK fields." +msgstr "Konfiguriert Berechtigungen für CCK-Felder auf Feldebene." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..7db1655a019f59031022df53fe697825f7ff1eee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.fr.po @@ -0,0 +1,49 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-10-19 18:01+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854 +#: modules/content_permissions/content_permissions.module:9 +msgid "edit " +msgstr "" + +# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854 +#: modules/content_permissions/content_permissions.module:9;10 +msgid "field_name" +msgstr "" + +# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854 +#: modules/content_permissions/content_permissions.module:10 +msgid "view " +msgstr "" + +#: modules/content_permissions/content_permissions.module:0 +msgid "content_permissions" +msgstr "content_permissions" + +#: modules/content_permissions/content_permissions.install:7 +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "Merci de <a href=\"!url\">configurer vos droits relatifs aux champs</a> immédiatement. Par défaut, tous les champs sont inaccessibles." + +#: modules/content_permissions/content_permissions.info:0 +msgid "Content Permissions" +msgstr "Droits sur le contenu" + +#: modules/content_permissions/content_permissions.info:0 +msgid "Set field-level permissions for CCK fields." +msgstr "Configurer les droits d'accès au niveau des champs pour les champs CCK." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..35e1496aa88e4aec76f8e0b70d23bc124381ed40 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.hu.po @@ -0,0 +1,52 @@ +# Hungarian translation of cck (6.x-2.0-rc10) +# Copyright (c) 2008 by the Hungarian translation team +# Generated from files: +# content_permissions.module,v 1.5.2.2 2008/10/06 15:11:39 karens +# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens +# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww +# +msgid "" +msgstr "" +"Project-Id-Version: cck (6.x-2.0-rc10)\n" +"POT-Creation-Date: 2008-10-31 12:16-0500\n" +"PO-Revision-Date: 2008-10-26 11:49-0500\n" +"Last-Translator: Balogh Zoltán\n" +"Language-Team: Drupal.hu Fordítói Csapat <forditas [at] drupal.hu>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: modules/content_permissions/content_permissions.module:9 +msgid "edit " +msgstr "szerkesztés " + +#: modules/content_permissions/content_permissions.module:9,10 +msgid "field_name" +msgstr "field_name" + +#: modules/content_permissions/content_permissions.module:10 +msgid "view " +msgstr "nézet " + +#: modules/content_permissions/content_permissions.module:0 +msgid "content_permissions" +msgstr "content_permissions" + +#: modules/content_permissions/content_permissions.install:9 +msgid "" +"Please <a href=\"!url\">configure your field permissions</a> " +"immediately. All fields are inaccessible by default." +msgstr "" +"Érdemes azonnal <a href=\"!url\">beállítani a mezők " +"jogosultságait</a>. Alapértelmezés szerint egyik mező sem érhető " +"el." + +#: modules/content_permissions/content_permissions.info:0 +msgid "Content Permissions" +msgstr "Tartalom Jogosultságok" + +#: modules/content_permissions/content_permissions.info:0 +msgid "Set field-level permissions for CCK fields." +msgstr "Mezőszintű jogosultságok beállítása." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.nl.po new file mode 100644 index 0000000000000000000000000000000000000000..d1023df9d9f003fb9873108cdfd9e849b17f2720 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.nl.po @@ -0,0 +1,56 @@ +# $Id$ +# +# Dutch translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content_permissions.module,v 1.5.2.5 2008/12/27 22:22:55 yched +# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens +# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-03 14:25+0200\n" +"PO-Revision-Date: 2009-06-03 14:25+0200\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: Dutch <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: content_permissions.module:10 +msgid "edit " +msgstr "bewerk" + +#: content_permissions.module:10;11 +msgid "field_name" +msgstr "field_name" + +#: content_permissions.module:11 +msgid "view " +msgstr "bekijk" + +#: content_permissions.module:0 +msgid "content_permissions" +msgstr "content_permissions" + +#: content_permissions.install:9 +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "" +"Stel <a href=\"!url\">je veldpermissies</a> direct in. Alle velden " +"zijn standaard niet te bekijken." + +#: content_permissions.info:0 +msgid "Content Permissions" +msgstr "Inhoudpermissies" + +#: content_permissions.info:0 +msgid "Set field-level permissions for CCK fields." +msgstr "Stel veldpermissies in voor CCK-velden." + +#: content_permissions.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.pot new file mode 100644 index 0000000000000000000000000000000000000000..1cdfa63e147377d69802bde2e0da067031cc5919 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.pot @@ -0,0 +1,50 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-content_permissions) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content_permissions.module,v 1.5.2.5 2008/12/27 22:22:55 yched +# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens +# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/content_permissions/content_permissions.module:10 +msgid "edit " +msgstr "" + +#: modules/content_permissions/content_permissions.module:10;11 +msgid "field_name" +msgstr "" + +#: modules/content_permissions/content_permissions.module:11 +msgid "view " +msgstr "" + +#: modules/content_permissions/content_permissions.module:0 +msgid "content_permissions" +msgstr "" + +#: modules/content_permissions/content_permissions.install:9 +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "" + +#: modules/content_permissions/content_permissions.info:0 +msgid "Content Permissions" +msgstr "" + +#: modules/content_permissions/content_permissions.info:0 +msgid "Set field-level permissions for CCK fields." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..4c2371bed92995115954444fde88b7cb66700ffe --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.sv.po @@ -0,0 +1,55 @@ +# $Id$ +# +# Swedish translation of Drupal (content_permissions) +# Generated from files: +# content_permissions.module,v 1.5.2.5 2008/12/27 22:22:55 yched +# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens +# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Content Permissions 6.x\n" +"POT-Creation-Date: 2009-05-27 13:07+0200\n" +"PO-Revision-Date: 2009-05-27 13:15+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: content_permissions.module:10 +msgid "edit " +msgstr "redigera" + +#: content_permissions.module:10;11 +msgid "field_name" +msgstr "fält_namn" + +#: content_permissions.module:11 +msgid "view " +msgstr "visa" + +#: content_permissions.module:0 +msgid "content_permissions" +msgstr "content_permissions" + +#: content_permissions.install:9 +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "Var vänlig <a href=\"!url\">konfigurera dina rättigheter för fält</a> omedelbart. Alla fält är som standard ej tillgängliga." + +#: content_permissions.info:0 +msgid "Content Permissions" +msgstr "Rättigheter för innehåll" + +#: content_permissions.info:0 +msgid "Set field-level permissions for CCK fields." +msgstr "Ange rättigheter per fältnivå för fält av typen CCK." + +#: content_permissions.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-rtl.css b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-rtl.css new file mode 100644 index 0000000000000000000000000000000000000000..0953e796cf895ebf33eff0c2146ccac9e93e3782 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-rtl.css @@ -0,0 +1,6 @@ +/* $Id$ */ + +div.fieldgroup .content { + padding-left:0; + padding-right:1em; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-simple.tpl.php b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-simple.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..bf24fc37c4cef3b83fd7d8922ea309aa442d7cb5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-simple.tpl.php @@ -0,0 +1,33 @@ +<?php +// $Id$ + +/** + * @file fieldgroup-simple.tpl.php + * Default theme implementation to display the a 'simple-styled' fieldgroup. + * + * Available variables: + * - $group_name - The group name + * - $group_name_css - The css-compatible group name. + * - $label - The group label + * - $description - The group description + * - $content - The group content + * + * @see template_preprocess_fieldgroup_simple() + */ +?> +<?php if ($content) : ?> +<div class="fieldgroup <?php print $group_name_css; ?>"> + + <?php if ($label): ?> + <h2><?php print $label; ?></h2> + + <?php if ($description): ?> + <div class="description"><?php print $description; ?></div> + <?php endif; ?> + + <?php endif; ?> + + <div class="content"><?php print $content; ?></div> + +</div> +<?php endif; ?> diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.css b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.css new file mode 100644 index 0000000000000000000000000000000000000000..bc86173e6f324ac9a24cffe24da4f2c90d7fcdfe --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.css @@ -0,0 +1,8 @@ +/* $Id$ */ + +div.fieldgroup { + margin:.5em 0 1em 0; +} +div.fieldgroup .content { + padding-left:1em;/*LTR*/ +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.info new file mode 100644 index 0000000000000000000000000000000000000000..260520b661c72726a25237ab00c454c5dc92312b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.info @@ -0,0 +1,12 @@ +; $Id$ +name = Fieldgroup +description = Create display groups for CCK fields. +dependencies[] = content +package = CCK +core = 6.x +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.install new file mode 100644 index 0000000000000000000000000000000000000000..da4b71ff183c01c9c3a8b400152f32bab0d1c5d7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.install @@ -0,0 +1,316 @@ +<?php +// $Id$ + +/** + * @file + * Implementation of hook_install(). + */ +function fieldgroup_install() { + drupal_load('module', 'content'); + db_query("UPDATE {system} SET weight = 9 WHERE name = 'fieldgroup'"); + drupal_install_schema('fieldgroup'); + content_notify('install', 'fieldgroup'); + variable_set('fieldgroup_schema_version', 6000); +} + + +/** + * Implementation of hook_uninstall(). + */ +function fieldgroup_uninstall() { + drupal_load('module', 'content'); + drupal_uninstall_schema('fieldgroup'); + content_notify('uninstall', 'fieldgroup'); +} + +/** + * Implementation of hook_enable(). + * + * Notify content module when this module is enabled. + */ +function fieldgroup_enable() { + drupal_load('module', 'content'); + content_notify('enable', 'fieldgroup'); +} + +/** + * Implementation of hook_disable(). + * + * Notify content module when this module is disabled. + */ +function fieldgroup_disable() { + drupal_load('module', 'content'); + content_notify('disable', 'fieldgroup'); +} + +/** + * Implementation of hook_schema. + */ +function fieldgroup_schema() { + $schema['content_group'] = array( + 'fields' => array( + 'group_type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => 'standard'), + 'type_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'group_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'label' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE), + 'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), + ), + 'primary key' => array('type_name', 'group_name'), + ); + + $schema['content_group_fields'] = array( + 'fields' => array( + 'type_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'group_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + 'field_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), + ), + 'primary key' => array('type_name', 'group_name', 'field_name'), + ); + + return $schema; +} + +/** + * rename groups form "group-*" to "group_*" + */ +function fieldgroup_update_1() { + $ret = array(); + if (!db_table_exists('node_group')) { + return $ret; + } + switch ($GLOBALS['db_type']) { + case 'pgsql': + $ret[] = update_sql("UPDATE {node_group} SET group_name = 'group_'||SUBSTRING(group_name FROM 7)"); + $ret[] = update_sql("UPDATE {node_group_fields} SET group_name = 'group_'||SUBSTRING(group_name FROM 7)"); + break; + + case 'mysql': + case 'mysqli': + $ret[] = update_sql("UPDATE {node_group} SET group_name = CONCAT('group_', SUBSTRING(group_name FROM 7))"); + $ret[] = update_sql("UPDATE {node_group_fields} SET group_name = CONCAT('group_', SUBSTRING(group_name FROM 7))"); + break; + } + return $ret; +} + +/** + * add display settings for the group + */ +function fieldgroup_update_2() { + $ret = array(); + if (!db_table_exists('node_group')) { + return $ret; + } + + // set settings column to accept larger values + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql('ALTER TABLE {node_group} CHANGE settings settings mediumtext NOT NULL'); + break; + + case 'pgsql': + db_change_column($ret, 'node_group', 'settings', 'settings', 'text', array('not null' => TRUE)); + break; + } + + // move description into the settings array, and add new settings + $result = db_query("SELECT * FROM {node_group}"); + while ($group = db_fetch_array($result)) { + $settings = array(); + $settings['form'] = unserialize($group['settings']); + $settings['form']['description'] = $group['description']; + $settings['display'] = array('collapsible' => 0, 'collapsed' => 0, 'description' => ''); + $ret[] = update_sql("UPDATE {node_group} SET settings = '". db_escape_string(serialize($settings)) ."', description = '' WHERE group_name = '". $group['group_name'] ."'"); + } + + // drop description column + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql('ALTER TABLE {node_group} DROP description'); + break; + + case 'pgsql': + // Postgres only supports dropping of columns since 7.4 + break; + } + + return $ret; +} + + +/** + * converts group settings collapsible/collapsed => style + */ +function fieldgroup_update_3() { + $ret = array(); + if (!db_table_exists('node_group')) { + return $ret; + } + $result = db_query("SELECT * FROM {node_group}"); + while ($group = db_fetch_array($result)) { + $group['settings'] = unserialize($group['settings']); + + if (!isset($group['settings']['form']['style'])) { + foreach (array('form', 'display') as $context) { + if (isset($group['settings'][$context]['collapsible']) && $group['settings'][$context]['collapsible']) { + if (isset($group['settings'][$context]['collapsed']) && $group['settings'][$context]['collapsed']) { + $group['settings'][$context]['style'] = 'fieldset_collapsed'; + } + else { + $group['settings'][$context]['style'] = 'fieldset_collapsible'; + } + } + else { + $group['settings'][$context]['style'] = 'fieldset'; + } + } + + $ret[] = update_sql("UPDATE {node_group} SET settings = '". db_escape_string(serialize($group['settings'])) ."' WHERE group_name = '". $group['group_name'] ."'"); + } + } + + return $ret; +} + +/* + * Increases module weight, so that other modules can form_alter() cck forms before the fields + * are moved in groups + */ +function fieldgroup_update_4() { + $ret = array(); + $ret[] = update_sql("UPDATE {system} SET weight = 9 WHERE name = 'fieldgroup'"); + return $ret; +} + + +/** + * Start D6 upgrades + */ + +/** + * Move fieldgroup tables to the content_* namespace. + */ +function fieldgroup_update_6000() { + if ($abort = content_check_update('fieldgroup')) { + return $abort; + } + + $ret = array(); + + db_rename_table($ret, 'node_group', 'content_group'); + db_rename_table($ret, 'node_group_fields', 'content_group_fields'); + variable_set('fieldgroup_schema_version', 6000); + return $ret; +} + +/* + * Increases module weight, so that other modules can form_alter() cck forms before the fields + * are moved in groups. + * + * Sites upgraded from D5 should have this already set. + * New D6 installs earlier than RC5 need this, as it was missing in fieldgroup_install. + */ +function fieldgroup_update_6001() { + if ($abort = content_check_update('fieldgroup')) { + return $abort; + } + + $ret = array(); + $ret[] = update_sql("UPDATE {system} SET weight = 9 WHERE name = 'fieldgroup'"); + return $ret; +} + +/** + * Same as 6000 : Move fieldgroup tables to the content_* namespace. + * This was missing in D6 releases earlier than RC5. Ensure we don't run this twice. + */ +function fieldgroup_update_6002() { + if ($abort = content_check_update('fieldgroup')) { + return $abort; + } + + $ret = array(); + if (db_table_exists('node_group')) { + db_rename_table($ret, 'node_group', 'content_group'); + db_rename_table($ret, 'node_group_fields', 'content_group_fields'); + variable_set('fieldgroup_schema_version', 6000); + } + return $ret; +} + +/** + * Remove tinyint (127) limitation on group weights. + */ +function fieldgroup_update_6003() { + if ($abort = content_check_update('fieldgroup')) { + return $abort; + } + + $ret = array(); + db_change_field($ret, 'content_group', 'weight', 'weight', array('type' => 'int', 'not null' => TRUE, 'default' => 0)); + return $ret; +} + +/** + * Add 'type' property for fieldgroups. + */ +function fieldgroup_update_6004() { + if ($abort = content_check_update('fieldgroup')) { + return $abort; + } + + $ret = array(); + db_add_field($ret, 'content_group', 'group_type', array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => 'standard')); + $ret[] = update_sql("DELETE FROM {cache_content} WHERE cid='fieldgroup_data'"); + return $ret; +} + +/** + * Add the 'exclude from $content' display setting to all existing groups. + */ +function fieldgroup_update_6005() { + $ret = array(); + $result = db_query("SELECT * FROM {content_group}"); + while ($type = db_fetch_array($result)) { + $new_settings = array(); + $settings = unserialize($type['settings']); + $new_settings = $settings; + $display_settings = !empty($settings['display']) ? $settings['display'] : array(); + if (!empty($display_settings)) { + foreach ($display_settings as $key => $val) { + $new_settings['display'][$key] = $val; + if ($key !== 'label' && is_array($val)) { + $new_settings['display'][$key]['exclude'] = 0; + } + } + } + else { + $new_settings['display'] = array( + 'label' => array('format' => 'above'), + 'full' => array('format' => 'default', 'exclude' => 0), + 'teaser' => array('format' => 'default', 'exclude' => 0), + ); + } + db_query("UPDATE {content_group} SET settings='%s' WHERE group_name='%s' AND type_name='%s'", serialize($new_settings), $type['group_name'], $type['type_name']); + } + return $ret; +} + +/** + * Removed a previous version of "Remove orphaned fields" (6007), broken for db prefixes. + */ +function fieldgroup_update_6006() { + return array(); +} + +/** + * Remove orphaned fields (see http://drupal.org/node/339537). + */ +function fieldgroup_update_6007() { + $ret = array(); + $ret[] = update_sql("DELETE FROM {content_group_fields} WHERE (field_name, type_name) NOT IN (SELECT field_name, type_name FROM {content_node_field_instance})"); + return $ret; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.module new file mode 100644 index 0000000000000000000000000000000000000000..3e0fdec7edcaa994cb191df38f07db7b80cecb44 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.module @@ -0,0 +1,913 @@ +<?php +// $Id$ + +/** + * @file + * Create field groups for CCK fields. + * + * Hooks for other modules to intervene include: + * - hook_fieldgroup_view: Alter the group $element added to $node->content. + * - hook_fieldgroup_form: Alter the group portion of the node form. + * - hook_fieldgroup_types: Add additional fieldgroup group_types. + * - hook_fieldgroup_default_settings: Add additional fieldgroup default settings. + * - hook_fieldgroup_save: Do additional processing when a fieldgroup is saved. + */ +/** + * Implementation of hook_init(). + */ +function fieldgroup_init() { + drupal_add_css(drupal_get_path('module', 'fieldgroup') .'/fieldgroup.css'); +} + +/** + * Implementation of hook_ctools_plugin_directory(). + */ +function fieldgroup_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && $plugin == 'content_types') { + return 'panels/' . $plugin; + } +} + +/** + * Implementation of hook_menu(). + */ +function fieldgroup_menu() { + $items = array(); + + // Make sure this doesn't fire until content_types is working, + // needed to avoid errors on initial installation. + if (!defined('MAINTENANCE_MODE')) { + foreach (node_get_types() as $type) { + $type_name = $type->type; + $content_type = content_types($type_name); + $type_url_str = $content_type['url_str']; + $items['admin/content/node-type/'. $type_url_str .'/groups/%'] = array( + 'title' => 'Edit group', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('fieldgroup_group_edit_form', $type_name, 5), + 'access arguments' => array('administer content types'), + 'type' => MENU_CALLBACK, + ); + $items['admin/content/node-type/'. $type_url_str .'/groups/%/remove'] = array( + 'title' => 'Edit group', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('fieldgroup_remove_group', $type_name, 5), + 'access arguments' => array('administer content types'), + 'type' => MENU_CALLBACK, + ); + } + } + return $items; +} + +/** + * Implementation of hook_theme(). + */ +function fieldgroup_theme() { + return array( + 'fieldgroup_simple' => array( + 'template' => 'fieldgroup-simple', + 'arguments' => array('element' => NULL), + ), + 'fieldgroup_fieldset' => array( + 'arguments' => array('element' => NULL), + ), + 'fieldgroup_display_overview_form' => array( + 'arguments' => array('form' => NULL), + ), + ); +} + +/** + * Implementation of hook_elements(). + */ +function fieldgroup_elements() { + return array( + 'fieldgroup_simple' => array(), + 'fieldgroup_fieldset' => array('#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL,), + ); +} + +/** + * Implementation of hook_fieldapi(). + */ +function fieldgroup_content_fieldapi($op, $field) { + switch ($op) { + case 'delete instance': + db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE field_name = '%s' AND type_name = '%s'", $field['field_name'], $field['type_name']); + cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE); + break; + } +} + +function fieldgroup_group_edit_form(&$form_state, $type_name, $group_name) { + $content_type = content_types($type_name); + $groups = fieldgroup_groups($content_type['type']); + + if (!$group = $groups[$group_name]) { + drupal_not_found(); + exit; + } + + $form['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#default_value' => $group['label'], + '#required' => TRUE, + ); + + // Set a default value for group type early in the form so it + // can be overridden by subsequent form elements added by other modules. + $group_type = !empty($group['group_type']) ? $group['group_type'] : 'standard'; + $form['group_type'] = array('#type' => 'hidden', '#default_value' => $group_type); + + $form['settings']['#tree'] = TRUE; + $form['settings']['form'] = array( + '#type' => 'fieldset', + '#title' => t('Form settings'), + '#description' => t('These settings apply to the group in the node editing form.'), + ); + $form['settings']['form']['style'] = array( + '#type' => 'radios', + '#title' => t('Style'), + '#default_value' => $group['settings']['form']['style'], + '#options' => array( + 'fieldset' => t('always open'), + 'fieldset_collapsible' => t('collapsible'), + 'fieldset_collapsed' => t('collapsed'), + ) + ); + $form['settings']['form']['description'] = array( + '#type' => 'textarea', + '#title' => t('Help text'), + '#default_value' => $group['settings']['form']['description'], + '#rows' => 5, + '#description' => t('Instructions to present to the user on the editing form.'), + '#required' => FALSE, + ); + $form['settings']['display'] = array( + '#type' => 'fieldset', + '#title' => t('Display settings'), + '#description' => t('These settings apply to the group on node display.'), + ); + $form['settings']['display']['description'] = array( + '#type' => 'textarea', + '#title' => t('Description'), + '#default_value' => $group['settings']['display']['description'], + '#rows' => 5, + '#description' => t('A description of the group.'), + '#required' => FALSE, + ); + + foreach (array_keys(content_build_modes()) as $key) { + $form['settings']['display'][$key]['format'] = array('#type' => 'value', '#value' => isset($group['settings']['display'][$key]['format']) ? $group['settings']['display'][$key]['format'] : 'fieldset'); + $form['settings']['display'][$key]['exclude'] = array('#type' => 'value', '#value' => isset($group['settings']['display'][$key]['exclude']) ? $group['settings']['display'][$key]['exclude'] : 0); + } + $form['settings']['display']['label'] = array('#type' => 'value', '#value' => $group['settings']['display']['label']); + $form['weight'] = array('#type' => 'hidden', '#default_value' => $group['weight']); + $form['group_name'] = array('#type' => 'hidden', '#default_value' => $group_name); + + $form['#content_type'] = $content_type; + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + '#weight' => 10, + ); + + return $form; +} + +function fieldgroup_group_edit_form_submit($form, &$form_state) { + $form_values = $form_state['values']; + $content_type = $form['#content_type']; + fieldgroup_save_group($content_type['type'], $form_values); + $form_state['redirect'] = 'admin/content/node-type/'. $content_type['url_str'] .'/fields'; +} + +function fieldgroup_remove_group(&$form_state, $type_name, $group_name) { + $content_type = content_types($type_name); + $groups = fieldgroup_groups($content_type['type']); + $group = isset($groups[$group_name]) ? $groups[$group_name] : ''; + + if (empty($group)) { + drupal_not_found(); + exit; + } + + $form['#submit'][] = 'fieldgroup_remove_group_submit'; + $form['#content_type'] = $content_type; + $form['#group_name'] = $group_name; + + return confirm_form($form, + t('Are you sure you want to remove the group %label?', + array('%label' => t($group['label']))), + 'admin/content/node-type/'. $content_type['url_str'] .'/fields', t('This action cannot be undone.'), + t('Remove'), t('Cancel')); +} + +function fieldgroup_remove_group_submit($form, &$form_state) { + $form_values = $form_state['values']; + $content_type = $form['#content_type']; + $group_name = $form['#group_name']; + fieldgroup_delete($content_type['type'], $group_name); + drupal_set_message(t('The group %group_name has been removed.', array('%group_name' => $group_name))); + $form_state['redirect'] = 'admin/content/node-type/'. $content_type['url_str'] .'/fields'; +} + +/** + * Returns all groups for a content type + */ +function fieldgroup_groups($content_type = '', $sorted = FALSE, $reset = FALSE) { + global $language; + static $groups, $groups_sorted; + if (!isset($groups) || $reset) { + if ($cached = cache_get('fieldgroup_data:'. $language->language, content_cache_tablename())) { + $data = $cached->data; + $groups = $data['groups']; + $groups_sorted = $data['groups_sorted']; + } + else { + $result = db_query("SELECT * FROM {". fieldgroup_tablename() ."} ORDER BY weight, group_name"); + $groups = array(); + $groups_sorted = array(); + while ($group = db_fetch_array($result)) { + $group['settings'] = unserialize($group['settings']); + $group['fields'] = array(); + + // Allow external modules to translate field group strings. + $group_strings = array( + 'label' => $group['label'], + 'form_description' => $group['settings']['form']['description'], + 'display_description' => $group['settings']['display']['description'], + ); + drupal_alter('content_fieldgroup_strings', $group_strings, $group['type_name'], $group['group_name']); + $group['label'] = $group_strings['label']; + $group['settings']['form']['description'] = $group_strings['form_description']; + $group['settings']['display']['description'] = $group_strings['display_description']; + + $groups[$group['type_name']][$group['group_name']] = $group; + $groups_sorted[$group['type_name']][] = &$groups[$group['type_name']][$group['group_name']]; + } + //load fields + $result = db_query("SELECT nfi.*, ng.group_name FROM {". fieldgroup_tablename() ."} ng ". + "INNER JOIN {". fieldgroup_fields_tablename() ."} ngf ON ngf.type_name = ng.type_name AND ngf.group_name = ng.group_name ". + "INNER JOIN {". content_instance_tablename() ."} nfi ON nfi.field_name = ngf.field_name AND nfi.type_name = ngf.type_name ". + "WHERE nfi.widget_active = 1 ORDER BY nfi.weight"); + while ($field = db_fetch_array($result)) { + // Allow external modules to translate field strings. + $field_strings = array( + 'widget_label' => $field['label'], + 'widget_description' => $field['description'], + ); + drupal_alter('content_field_strings', $field_strings, $field['type_name'], $field['field_name']); + $field['label'] = $field_strings['widget_label']; + $field['description'] = $field_strings['widget_description']; + + $groups[$field['type_name']][$field['group_name']]['fields'][$field['field_name']] = $field; + } + cache_set('fieldgroup_data:'. $language->language, array('groups' => $groups, 'groups_sorted' => $groups_sorted), content_cache_tablename()); + } + } + if (empty($content_type)) { + return $groups; + } + elseif (empty($groups) || empty($groups[$content_type])) { + return array(); + } + return $sorted ? $groups_sorted[$content_type] : $groups[$content_type]; +} + + +function _fieldgroup_groups_label($content_type) { + $groups = fieldgroup_groups($content_type); + + $labels[''] = '<'. t('none') .'>'; + foreach ($groups as $group_name => $group) { + $labels[$group_name] = t($group['label']); + } + return $labels; +} + +function _fieldgroup_field_get_group($content_type, $field_name) { + return db_result(db_query("SELECT group_name FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $content_type, $field_name)); +} + +/** + * Implementation of hook_form_alter() + */ +function fieldgroup_form_alter(&$form, $form_state, $form_id) { + if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) { + foreach (fieldgroup_groups($form['type']['#value']) as $group_name => $group) { + $form[$group_name] = array( + '#type' => 'fieldset', + '#title' => check_plain(t($group['label'])), + '#collapsed' => $group['settings']['form']['style'] == 'fieldset_collapsed', + '#collapsible' => in_array($group['settings']['form']['style'], array('fieldset_collapsed', 'fieldset_collapsible')), + '#weight' => $group['weight'], + '#description' => content_filter_xss(t($group['settings']['form']['description'])), + '#attributes' => array('class' => strtr($group['group_name'], '_', '-')), + ); + + $has_accessible_field = FALSE; + foreach ($group['fields'] as $field_name => $field) { + if (isset($form[$field_name])) { + $form[$group_name][$field_name] = $form[$field_name]; + // Track whether this group has any accessible fields within it. + if (!isset($form[$field_name]['#access']) || $form[$field_name]['#access'] !== FALSE) { + $has_accessible_field = TRUE; + } + unset($form[$field_name]); + } + } + if (!empty($group['fields']) && !element_children($form[$group_name])) { + //hide the fieldgroup, because the fields are hidden too + unset($form[$group_name]); + } + + if (!$has_accessible_field) { + // Hide the fieldgroup, because the fields are inaccessible. + $form[$group_name]['#access'] = FALSE; + } + + // Allow other modules to alter the form. + // Can't use module_invoke_all because we want + // to be able to use a reference to $form and $form_state. + foreach (module_implements('fieldgroup_form') as $module) { + $function = $module .'_fieldgroup_form'; + $function($form, $form_state, $form_id, $group); + } + + } + + } + // The group is only added here so it will appear in the export + // when using Content Copy. + elseif ($form_id == 'content_field_edit_form' && isset($form['widget'])) { + $content_type = content_types($form['type_name']['#value']); + $form['widget']['group'] = array( + '#type' => 'value', + '#value' => _fieldgroup_field_get_group($content_type['type'], $form['field_name']['#value']), + ); + } + elseif ($form_id == 'content_field_overview_form') { + $form['#validate'][] = 'fieldgroup_field_overview_form_validate'; + $form['#submit'][] = 'fieldgroup_field_overview_form_submit'; + } + elseif ($form_id == 'content_display_overview_form' && !empty($form['#groups'])) { + $form['#submit'][] = 'fieldgroup_display_overview_form_submit'; + if (!isset($form['submit'])) { + $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 10); + } + } + elseif ($form_id == 'content_field_remove_form') { + $form['#submit'][] = 'fieldgroup_field_remove_form_submit'; + } +} + +/** + * API for group name validation. + * + * Pulled into separate function to be re-usable. + */ +function fieldgroup_validate_name($group, $type_name) { + $errors = array(); + + // No label. + if (!$group['label']) { + $errors['label'][] = t('You need to provide a label.'); + } + + // No group name. + if (!$group['group_name']) { + $errors['group_name'][] = t('You need to provide a group name.'); + } + // Group name validation. + else { + $group_name = $group['group_name']; + $group['group_type'] = !empty($group['group_type']) ? $group['group_type'] : 'standard'; + + // Add the 'group_' prefix. + if (substr($group_name, 0, 6) != 'group_') { + $group_name = 'group_'. $group_name; + } + + // Invalid field name. + if (!preg_match('!^group_[a-z0-9_]+$!', $group_name)) { + $errors['group_name'][] = t('The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores.', array('%group_name' => $group_name)); + } + if (strlen($group_name) > 32) { + $errors['group_name'][] = t('The group name %group_name is too long. The name is limited to 32 characters, including the \'group_\' prefix.', array('%group_name' => $group_name)); + } + + // Group name already exists. + $groups = fieldgroup_groups($type_name); + if (isset($groups[$group_name])) { + $errors['group_name'][] = t('The group name %group_name already exists.', array('%group_name' => $group_name)); + } + if (empty($errors['group_name'])) { + $group['group_name'] = $group_name; + } + } + return array('group_name' => $group['group_name'], 'errors' => $errors); +} + +function fieldgroup_field_overview_form_validate($form, &$form_state) { + $form_values = $form_state['values']; + $group = $form_values['_add_new_group']; + + if (array_filter(array($group['label'], $group['group_name']))) { + $validation = fieldgroup_validate_name($group, $form['#type_name']); + if (!empty($validation['errors'])) { + foreach ($validation['errors'] as $type => $messages) { + foreach ($messages as $message) { + if ($type == 'label') { + form_set_error('_add_new_group][label', t('Add new group:') .' '. $message); + } + else { + form_set_error('_add_new_group][group_name', t('Add new group:') .' '. $message); + } + } + } + } + $group_name = $validation['group_name']; + form_set_value($form['_add_new_group']['group_name'], $group_name, $form_state); + } + else { + // Fail validation if attempt to nest fields under a new group without the + // proper information. Not raising an error would cause the nested fields + // to get weights the user doesn't expect. + + foreach ($form_values as $key => $values) { + if ($values['parent'] == '_add_new_group') { + form_set_error('_add_new_group][label', t('Add new group: you need to provide a label.')); + form_set_error('_add_new_group][group_name', t('Add new group: you need to provide a group name.')); + break; + } + } + } +} + +function fieldgroup_field_overview_form_submit($form, &$form_state) { + $form_values = $form_state['values']; + $type_name = $form['#type_name']; + + // Create new group if needed. + if (!empty($form_values['_add_new_group']['label'])) { + $group = $form_values['_add_new_group']; + $group['settings'] = field_group_default_settings($group['group_type']); + fieldgroup_save_group($type_name, $group); + $new_group_name = $group['group_name']; + } + + // Parse incoming rows. + $add_field_rows = array('_add_new_field', '_add_existing_field'); + $field_rows = array_merge($form['#fields'], $add_field_rows); + foreach ($form_values as $key => $values) { + // If 'field' row: update field parenting. + if (in_array($key, $field_rows)) { + // If newly added fields were added to a group: + if (in_array($key, $add_field_rows)) { + // We replace the '_add_*_field' key with the actual name of + // the field that got added. + // content_field_overview_form_submit() placed those + // in $form_state['fields_added'] for us. + if (isset($form_state['fields_added'][$key])) { + $key = $form_state['fields_added'][$key]; + } + else { + // No field was actually created : skip to next row. + continue; + } + } + // If the field was added to the newly created group, replace the + // '_add_new_group' value with the actual name of the group. + $parent = ($values['parent'] == '_add_new_group' && isset($new_group_name)) ? $new_group_name : $values['parent']; + // TODO: check the parent group does exist ? + fieldgroup_update_fields(array('field_name' => $key, 'group' => $parent, 'type_name' => $type_name)); + } + + // If 'group' row: update groups weights + // (possible newly created group has already been taken care of). + elseif (in_array($key, $form['#groups'])) { + db_query("UPDATE {". fieldgroup_tablename() ."} SET weight = %d WHERE type_name = '%s' AND group_name = '%s'", + $values['weight'], $type_name, $key); + } + } + + cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE); +} + +function field_group_default_settings($group_type) { + $settings = array( + 'form' => array('style' => 'fieldset', 'description' => ''), + 'display' => array('description' => '', 'label' => 'above'), + ); + module_load_include('inc', 'content', 'includes/content.admin'); + foreach (array_keys(content_build_modes()) as $key) { + $settings['display'][$key]['format'] = 'fieldset'; + $settings['display'][$key]['exclude'] = 0; + } + // Allow other modules to add new default settings. + $settings = array_merge($settings, module_invoke_all('fieldgroup_default_settings', $group_type)); + return $settings; +} + +function fieldgroup_display_overview_form_submit($form, &$form_state) { + $form_values = $form_state['values']; + $groups = fieldgroup_groups($form['#type_name']); + foreach ($form_values as $key => $values) { + if (in_array($key, $form['#groups'])) { + $group = $groups[$key]; + // We have some numeric keys here, so we can't use array_merge. + $group['settings']['display'] = $values + $group['settings']['display']; + fieldgroup_save_group($form['#type_name'], $group); + } + } +} + +function fieldgroup_field_remove_form_submit($form, &$form_state) { + $form_values = $form_state['values']; + // TODO: + // - when a (non last) field is removed from a group, a 'ghost row' remains in the fields overview + // - when the last field is removed, the group disappears + // seems to be fixed when emptying the cache. + db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $form_values['type_name'], $form_values['field_name']); +} + +/** + * Implementation of hook_nodeapi(). + */ +function fieldgroup_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) { + switch ($op) { + case 'view': + // Prevent against invalid 'nodes' built by broken 3rd party code. + if (isset($node->type)) { + // Build the node content element needed to render each fieldgroup. + foreach (fieldgroup_groups($node->type) as $group) { + fieldgroup_build_content($group, $node, $teaser, $page); + } + } + break; + } +} + +/** + * Build the node content element needed to render a fieldgroup. + * + * @param $group + * The field group definition. + * @param $node + * The node containing the field group to display. Can be a 'pseudo-node', + * containing at least 'type', 'nid', 'vid', and the content for fields + * required for the group. + * @param $teaser + * @param $page + * Similar to hook_nodeapi('view'). + * + * @see fieldgroup_nodeapi() + * @see fieldgroup_view_group() + */ +function fieldgroup_build_content($group, &$node, $teaser, $page) { + // NODE_BUILD_NORMAL is 0, and ('whatever' == 0) is TRUE, so we need a ===. + if ($node->build_mode === NODE_BUILD_NORMAL || $node->build_mode == NODE_BUILD_PREVIEW) { + $context = $teaser ? 'teaser' : 'full'; + } + else { + $context = $node->build_mode; + } + + $group_name = $group['group_name']; + + // Do not include group labels when indexing content. + if ($context == NODE_BUILD_SEARCH_INDEX) { + $group['settings']['display']['label'] = 'hidden'; + } + $label = $group['settings']['display']['label'] == 'above'; + $element = array( + '#title' => $label ? check_plain(t($group['label'])) : '', + '#description' => $label ? content_filter_xss(t($group['settings']['display']['description'])) : '', + ); + $format = isset($group['settings']['display'][$context]['format']) ? $group['settings']['display'][$context]['format'] : 'fieldset'; + + switch ($format) { + case 'simple': + $element['#type'] = 'fieldgroup_simple'; + $element['#group_name'] = $group_name; + $element['#node'] = $node; + break; + case 'hidden': + $element['#access'] = FALSE; + break; + case 'fieldset_collapsed': + $element['#collapsed'] = TRUE; + case 'fieldset_collapsible': + $element['#collapsible'] = TRUE; + case 'fieldset': + $element['#type'] = 'fieldgroup_fieldset'; + $element['#attributes'] = array('class' => 'fieldgroup '. strtr($group['group_name'], '_', '-')); + break; + } + foreach ($group['fields'] as $field_name => $field) { + if (isset($node->content[$field_name])) { + $element[$field_name] = $node->content[$field_name]; + } + } + + // Allow other modules to alter the group view. + // Can't use module_invoke_all because we want + // to be able to use a reference to $node and $element. + foreach (module_implements('fieldgroup_view') as $module) { + $function = $module .'_fieldgroup_view'; + $function($node, $element, $group, $context); + } + + // Unset the original field values now that we've moved them. + foreach ($group['fields'] as $field_name => $field) { + if (isset($node->content[$field_name])) { + unset($node->content[$field_name]); + } + } + + // The wrapper lets us get the themed output for the group + // to populate the $GROUP_NAME_rendered variable for node templates, + // and hide it from the $content variable if needed. + // See fieldgroup_preprocess_node(), theme_fieldgroup_wrapper(). + $wrapper = array( + 'group' => $element, + '#weight' => $group['weight'], + '#post_render' => array('fieldgroup_wrapper_post_render'), + '#group_name' => $group_name, + '#type_name' => $node->type, + '#context' => $context, + ); + + $node->content[$group_name] = $wrapper; +} + +/** + * Render a single field group, fully themed with label. + * + * To be used by third-party code (Panels, ...) that needs to output an + * isolated field group. Do *not* use inside node templates, use the + * $GROUP_NAME_rendered variables instead. You can also use the 'simple' + * style format and override the template fieldgroup-simple.tpl.php. + * + * By default, the field group is displayed using the settings defined for the + * 'full node' or 'teaser' contexts (depending on the value of the $teaser param). + * Set $node->build_mode to a different value to use a different context. + * + * Different settings can be specified by adjusting $group['settings']['display']. + * + * @param $group + * The field group definition. + * @param $node + * The node containing the field group to display. Can be a 'pseudo-node', + * containing at least 'type', 'nid', 'vid', and the field data required + * for the group. + * @param $teaser + * @param $page + * Similar to hook_nodeapi('view'). + * @return + * The themed output for the field group. + * + * @see content_view_field() + */ +function fieldgroup_view_group($group, &$node, $teaser = FALSE, $page = FALSE) { + $group_name = $group['group_name']; + $field_types = _content_field_types(); + + // Clone the node to prevent from altering the original. + $node_copy = drupal_clone($node); + + // Use 'full'/'teaser' if not specified otherwise. + $node_copy->build_mode = isset($node_copy->build_mode) ? $node_copy->build_mode : NODE_BUILD_NORMAL; + + // Build the content element for individual fields in the field group. + if (!isset($node_copy->content)) { + $node_copy->content = array(); + } + foreach (array_keys($group['fields']) as $field_name) { + $field = content_fields($field_name, $node_copy->type); + + if (isset($node_copy->{$field_name})) { + $items = $node_copy->{$field_name}; + + // One-field equivalent to _content_field_invoke('sanitize'). + $module = $field_types[$field['type']]['module']; + $function = $module .'_field'; + if (function_exists($function)) { + $function('sanitize', $node_copy, $field, $items, $teaser, $page); + $node_copy->{$field_name} = $items; + } + + $field_view = content_field('view', $node_copy, $field, $items, $teaser, $page); + // content_field('view') adds a wrapper to handle variables and 'excluded' + // fields for node templates. We bypass it and get the actual field. + $node_copy->content[$field_name] = $field_view[$field_name]; + } + } + + // Build the content element of the field group itself. + fieldgroup_build_content($group, $node_copy, $teaser, $page); + + // fieldgroup_build_content() adds a wrapper to handle variables and 'excluded' + // groups for node templates. We bypass it and render the actual field group. + $output = drupal_render($node_copy->content[$group_name]['group']); + + return $output; +} + +/** + * Hide specified fields from the $content variable in node templates. + */ +function fieldgroup_wrapper_post_render($content, $element) { + $groups = fieldgroup_groups($element['#type_name']); + $group = $groups[$element['#group_name']]; + + // The display settings are not in quite the same place in the + // group and the field, so create the value the theme will expect. + $group['display_settings'] = $group['settings']['display']; + if (theme('content_exclude', $content, $group, $element['#context'])) { + return ''; + } + return $content; +} + +/* + * Get the group name for a field. + * If the field isn't in a group, FALSE will be returned. + * @return The name of the group, or FALSE. + */ +function fieldgroup_get_group($content_type, $field_name) { + foreach (fieldgroup_groups($content_type) as $group_name => $group) { + if (in_array($field_name, array_keys($group['fields']))) { + return $group_name; + } + } + return FALSE; +} + +/** + * Implementation of hook_node_type() + * React to change in node types + */ +function fieldgroup_node_type($op, $info) { + if ($op == 'update' && !empty($info->old_type) && $info->type != $info->old_type) { + // update the tables + db_query("UPDATE {". fieldgroup_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type)); + db_query("UPDATE {". fieldgroup_fields_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type)); + cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE); + } + elseif ($op == 'delete') { + db_query("DELETE FROM {". fieldgroup_tablename() ."} WHERE type_name = '%s'", $info->type); + db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s'", $info->type); + } +} + +function fieldgroup_types() { + $types = array('standard' => t('Standard group')); + // Allow other modules to add new group_types. + $types = array_merge($types, module_invoke_all('fieldgroup_types')); + return $types; +} + +function fieldgroup_tablename($version = NULL) { + if (is_null($version)) { + $version = variable_get('fieldgroup_schema_version', 0); + } + return $version < 6000 ? 'node_group' : 'content_group'; +} + +function fieldgroup_fields_tablename($version = NULL) { + if (is_null($version)) { + $version = variable_get('fieldgroup_schema_version', 0); + } + return $version < 6000 ? 'node_group_fields' : 'content_group_fields'; +} + +/** + * CRUD API for fieldgroup module. + * + * @todo + * Make this into more of a real API for groups. + */ +/* + * Saves the given group for this content-type + */ +function fieldgroup_save_group($type_name, $group) { + $groups = fieldgroup_groups($type_name); + + // Allow other modules to intervene when the group is saved. + foreach (module_implements('fieldgroup_save_group') as $module) { + $function = $module .'_fieldgroup_save_group'; + $function($group); + } + + if (!isset($groups[$group['group_name']])) { + // Accept group name from programmed submissions if valid. + db_query("INSERT INTO {". fieldgroup_tablename() ."} (group_type, type_name, group_name, label, settings, weight)". + " VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $group['group_type'], $type_name, $group['group_name'], $group['label'], serialize($group['settings']), $group['weight']); + cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE); + return SAVED_NEW; + } + else { + db_query("UPDATE {". fieldgroup_tablename() ."} SET group_type = '%s', label = '%s', settings = '%s', weight = %d ". + "WHERE type_name = '%s' AND group_name = '%s'", + $group['group_type'], $group['label'], serialize($group['settings']), $group['weight'], $type_name, $group['group_name']); + cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE); + return SAVED_UPDATED; + } +} + +function fieldgroup_update_fields($form_values) { + $default = _fieldgroup_field_get_group($form_values['type_name'], $form_values['field_name']); + + if ($default != $form_values['group']) { + if ($form_values['group'] && !$default) { + db_query("INSERT INTO {". fieldgroup_fields_tablename() ."} (type_name, group_name, field_name) VALUES ('%s', '%s', '%s')", $form_values['type_name'], $form_values['group'], $form_values['field_name']); + } + elseif ($form_values['group']) { + db_query("UPDATE {". fieldgroup_fields_tablename() ."} SET group_name = '%s' WHERE type_name = '%s' AND field_name = '%s'", $form_values['group'], $form_values['type_name'], $form_values['field_name']); + } + else { + db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $form_values['type_name'], $form_values['field_name']); + } + cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE); + } +} + +function fieldgroup_delete($content_type, $group_name) { + db_query("DELETE FROM {". fieldgroup_tablename() ."} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $group_name); + db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $group_name); + cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE); +} + +/** + * Format a fieldgroup using a 'fieldset'. + * + * Derived from core's theme_fieldset, with no output if the content is empty. + */ +function theme_fieldgroup_fieldset($element) { + if (empty($element['#children']) && empty($element['#value'])) { + return ''; + } + + if ($element['#collapsible']) { + drupal_add_js('misc/collapse.js'); + + if (!isset($element['#attributes']['class'])) { + $element['#attributes']['class'] = ''; + } + + $element['#attributes']['class'] .= ' collapsible'; + if ($element['#collapsed']) { + $element['#attributes']['class'] .= ' collapsed'; + } + } + return '<fieldset'. drupal_attributes($element['#attributes']) .'>'. ($element['#title'] ? '<legend>'. $element['#title'] .'</legend>' : '') . (isset($element['#description']) && $element['#description'] ? '<div class="description">'. $element['#description'] .'</div>' : '') . (!empty($element['#children']) ? $element['#children'] : '') . (isset($element['#value']) ? $element['#value'] : '') ."</fieldset>\n"; +} + + +/** + * Process variables for fieldgroup.tpl.php. + * + * The $variables array contains the following arguments: + * - $group_name + * - $group_name_css + * - $label + * - $description + * - $content + * + * @see fieldgroup-simple.tpl.php + */ +function template_preprocess_fieldgroup_simple(&$vars) { + $element = $vars['element']; + + $vars['group_name'] = $element['#group_name']; + $vars['group_name_css'] = strtr($element['#group_name'], '_', '-'); + $vars['label'] = isset($element['#title']) ? $element['#title'] : '';; + $vars['description'] = isset($element['#description']) ? $element['#description'] : '';; + $vars['content'] = isset($element['#children']) ? $element['#children'] : ''; + $vars['template_files'] = array( + 'fieldgroup-simple-', + 'fieldgroup-simple-'. $element['#group_name'], + 'fieldgroup-simple-'. $element['#node']->type, + 'fieldgroup-simple-'. $element['#group_name'] .'-'. $element['#node']->type, + ); +} + +/** + * Theme preprocess function for node. + * + * Adds $GROUP_NAME_rendered variables, + * containing the themed output for the whole group. + */ +function fieldgroup_preprocess_node(&$vars) { + $node = $vars['node']; + + foreach (fieldgroup_groups($node->type) as $group_name => $group) { + // '#chilren' might not be set if the group is empty. + $vars[$group_name .'_rendered'] = isset($node->content[$group_name]['#children']) ? $node->content[$group_name]['#children'] : ''; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/content_fieldgroup.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/content_fieldgroup.inc new file mode 100644 index 0000000000000000000000000000000000000000..dc462c586e1e25716648051cfb7cec4ef8ab4012 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/content_fieldgroup.inc @@ -0,0 +1,164 @@ +<?php +// $Id$ + +/** + * @file + * This file provides a CTools content type for fieldgroups. + */ + +/** + * Callback function to supply a list of content types. + */ +function fieldgroup_content_fieldgroup_ctools_content_types() { + return array( + 'title' => t('Content fieldgroup'), + 'defaults' => array('label' => 'hidden', 'format' => 'simple', 'empty' => ''), + ); +} + +/** + * Return all fieldgroup content types available. + */ +function fieldgroup_content_fieldgroup_content_type_content_types() { + // This will hold all the individual fieldgroup content types. + $types = array(); + + // The outer loop goes through each node type with groups. + foreach (fieldgroup_groups() as $node_type_groups) { + // The inner loop gives us each fieldgroup on each node type with groups. + foreach ($node_type_groups as $group) { + // Skip field groups that are not of standard type. + if ($group['group_type'] != 'standard') { + continue; + } + + // Name the content type a combination of fieldgroup and node type names. + $content_type_name = $group['type_name'] . ':' . $group['group_name']; + + // Assemble the information about the content type. + $info = array( + 'category' => t('Node'), + 'icon' => 'icon_cck_field_group.png', + 'title' => t('Field group: @group in @type', array( + '@group' => t($group['label']), + '@type' => node_get_types('name', $group['type_name']), + )), + 'description' => t('All fields from this field group on the referenced node.'), + 'required context' => new ctools_context_required(t('Node'), 'node', array('type' => array($group['type_name']))), + ); + + $types[$content_type_name] = $info; + } + } + + return $types; +} + +/** + * Output function for the 'fieldgroup' content type. + */ +function fieldgroup_content_fieldgroup_content_type_render($subtype, $conf, $panel_args, $context) { + if (!isset($context->data)) { + return; + } + $node = drupal_clone($context->data); + + // Make sure old data doesn't cause problems: + if (empty($conf['label'])) { + $conf['label'] = 'hidden'; + } + if (empty($conf['format'])) { + $conf['format'] = 'simple'; + } + + // Extract the node type and fieldgroup name from the subtype. + list($node_type, $group_name) = explode(':', $subtype, 2); + + // Get a list of all fieldgroups for this node type. + $groups = fieldgroup_groups($node_type); + + if (!isset($groups[$group_name])) { + return; + } + $group = $groups[$group_name]; + + // Render the field group. + $node->build_mode = NODE_BUILD_NORMAL; + $group['settings']['display']['label'] = $conf['label'] == 'normal' || !empty($conf['override_title']) ? 'hidden' : $conf['label']; + $group['settings']['display']['full']['format'] = $conf['format']; + $group['settings']['display']['full']['exclude'] = 0; + $output = fieldgroup_view_group($group, $node); + + $block = new stdClass(); + if ($conf['label'] == 'normal') { + $block->title = t($group['label']); + } + $block->content = !empty($output) ? $output : $conf['empty']; + return $block; +} + +/** + * Returns a settings form for the custom type. + */ +function fieldgroup_content_fieldgroup_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $label_options = array( + 'normal' => t('Block title'), + 'above' => t('Above'), + ); + $form['label'] = array( + '#type' => 'select', + '#title' => t('Field group label'), + '#default_value' => !empty($conf['label']) && isset($label_options[$conf['label']]) ? $conf['label'] : 'hidden', + '#options' => $label_options, + '#description' => t('Configure how the field group label is going to be displayed. This option takes no effect when "Override title" option is enabled, the specified block title is displayed instead.'), + ); + + $format_options = array( + 'simple' => t('Simple'), + 'fieldset' => t('Fieldset'), + 'fieldset_collapsible' => t('Fieldset - Collapsible'), + 'fieldset_collapsed' => t('Fieldset - Collapsed'), + ); + $form['format'] = array( + '#type' => 'select', + '#title' => t('Field group format'), + '#default_value' => !empty($conf['format']) && isset($format_options[$conf['format']]) ? $conf['format'] : 'simple', + '#options' => $format_options, + '#description' => t('This option allows you to configure the field group format.'), + ); + + $form['empty'] = array( + '#type' => 'textarea', + '#title' => t('Empty text'), + '#description' => t('Text to display if group has no data. Note that title will not display unless overridden.'), + '#rows' => 5, + '#default_value' => $conf['empty'], + ); +} + +function fieldgroup_content_fieldgroup_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Admin title for fieldgroup content type. + */ +function fieldgroup_content_fieldgroup_content_type_admin_title($subtype, $conf, $context) { + // Extract the node type and fieldgroup name from the subtype. + list($node_type, $group_name) = explode(':', $subtype, 2); + + // Get information about this field group for this node type. + $groups = fieldgroup_groups($node_type); + $group = $groups[$group_name]; + + return t('"@s" field group: @group in @type', array( + '@s' => $context->identifier, + '@group' => t($group['label']), + '@type' => node_get_types('name', $node_type), + )); +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/icon_cck_field_group.png b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/icon_cck_field_group.png new file mode 100644 index 0000000000000000000000000000000000000000..84594431b705009714e569d99bf3a2739c42b7f5 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/icon_cck_field_group.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.de.po new file mode 100644 index 0000000000000000000000000000000000000000..3f6a582b63463077b6fe6e8639ed873dcf28b933 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.de.po @@ -0,0 +1,42 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:08+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:39 +msgid "@type: (fieldgroup) @fieldgroup" +msgstr "@type: (Feldgruppe) @fieldgroup" + +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:42 +msgid "All fields from this fieldgroup on the referenced node." +msgstr "Alle Felder einer Feldgruppe auf dem referenzierten Beitrag." + +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:119 +msgid "\"@s\" fieldgroup (@name)" +msgstr "„@s“ Feldgruppe (@name)" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.pot new file mode 100644 index 0000000000000000000000000000000000000000..d97357a14513cdc134b41c6684ba58173304db5a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.pot @@ -0,0 +1,31 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-fieldgroup-panels-content_types) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from file: content_fieldgroup.inc,v 1.1.2.1 2009/04/29 18:34:46 karens +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:39 +msgid "@type: (fieldgroup) @fieldgroup" +msgstr "" + +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:42 +msgid "All fields from this fieldgroup on the referenced node." +msgstr "" + +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:119 +msgid "\"@s\" fieldgroup (@name)" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.de.po new file mode 100644 index 0000000000000000000000000000000000000000..b9af7104d2d37433e07aff61a0182351d01245a9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.de.po @@ -0,0 +1,151 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:06+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/fieldgroup/fieldgroup.panels.inc:30 +msgid "All fields from a fieldgroup on the referenced node." +msgstr "Alle Felder einer Feldgruppe auf dem referenzierten Beitrag." + +#: modules/fieldgroup/fieldgroup.panels.inc:32 +msgid "Node context" +msgstr "Beitragskontext" + +#: modules/fieldgroup/fieldgroup.panels.inc:91 +msgid "@group_label (@group_type_name)" +msgstr "@group_label (@group_type_name)" + +#: modules/fieldgroup/fieldgroup.panels.inc:102 +#: modules/fieldgroup/fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "Feldgruppe" + +#: modules/fieldgroup/fieldgroup.panels.inc:128 +msgid "\"@s\" fieldgroup @name" +msgstr "„@s“ Feldgruppe @name" + +#: modules/fieldgroup/fieldgroup.module:130 +msgid "Form settings" +msgstr "Formulareinstellungen" + +#: modules/fieldgroup/fieldgroup.module:131 +msgid "These settings apply to the group in the node editing form." +msgstr "Diese Einstellungen gelten für die Gruppe im Bearbeitungsformular des Beitrages." + +#: modules/fieldgroup/fieldgroup.module:135 +msgid "Style" +msgstr "Darstellung" + +#: modules/fieldgroup/fieldgroup.module:138 +msgid "always open" +msgstr "Immer geöffnet" + +#: modules/fieldgroup/fieldgroup.module:139 +msgid "collapsible" +msgstr "Zusammenklappbar" + +#: modules/fieldgroup/fieldgroup.module:140 +msgid "collapsed" +msgstr "Zusammengeklappt" + +#: modules/fieldgroup/fieldgroup.module:148 +msgid "Instructions to present to the user on the editing form." +msgstr "Eine Hilfestellung, die dem Benutzer im Bearbeitungsformular angezeigt wird." + +#: modules/fieldgroup/fieldgroup.module:153 +msgid "Display settings" +msgstr "Anzeigeeinstellungen" + +#: modules/fieldgroup/fieldgroup.module:154 +msgid "These settings apply to the group on node display." +msgstr "Diese Einstellungen gelten bei der Beitragsanzeige für die Gruppe." + +#: modules/fieldgroup/fieldgroup.module:161 +msgid "A description of the group." +msgstr "Eine Beschreibung der Gruppe." + +#: modules/fieldgroup/fieldgroup.module:206 +msgid "Are you sure you want to remove the group %label?" +msgstr "Soll die Gruppe %label wirklich gelöscht werden?" + +#: modules/fieldgroup/fieldgroup.module:208 +msgid "This action cannot be undone." +msgstr "Dieser Vorgang kann nicht rückgängig gemacht werden." + +#: modules/fieldgroup/fieldgroup.module:217 +msgid "The group %group_name has been removed." +msgstr "Die Gruppe %group_name wurde gelöscht." + +#: modules/fieldgroup/fieldgroup.module:359 +msgid "You need to provide a label." +msgstr "Eine Bezeichnung muss angegeben werden." + +#: modules/fieldgroup/fieldgroup.module:364 +msgid "You need to provide a group name." +msgstr "Ein Gruppenname muss angegeben werden." + +#: modules/fieldgroup/fieldgroup.module:378 +msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Der Gruppenname %group_name ist ungültig. Der Name darf nur nicht-akzentuierte Kleinbuchstaben, Zahlen und Unterstriche enthalten." + +#: modules/fieldgroup/fieldgroup.module:381 +msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix." +msgstr "Der Gruppenname %group_name ist zu lang. Der Name ist inklusive dem Präfix ‚group_‘ auf 32 Zeichen begrenzt." + +#: modules/fieldgroup/fieldgroup.module:387 +msgid "The group name %group_name already exists." +msgstr "Der Gruppenname %group_name ist schon vorhanden." + +#: modules/fieldgroup/fieldgroup.module:406;409 +msgid "Add new group:" +msgstr "Neue Gruppe hinzufügen:" + +#: modules/fieldgroup/fieldgroup.module:424 +msgid "Add new group: you need to provide a label." +msgstr "Neue Gruppe hinzufügen: Eine Bezeichnung muss angegeben werden." + +#: modules/fieldgroup/fieldgroup.module:425 +msgid "Add new group: you need to provide a group name." +msgstr "Neue Gruppe hinzufügen: Ein Gruppenname muss angegeben werden." + +#: modules/fieldgroup/fieldgroup.module:654 +msgid "Standard group" +msgstr "Standard-Gruppe" + +#: modules/fieldgroup/fieldgroup.module:45;52 +msgid "Edit group" +msgstr "Gruppe bearbeiten" + +#: modules/fieldgroup/fieldgroup.module:0 +msgid "fieldgroup" +msgstr "Feldgruppe" + +#: modules/fieldgroup/fieldgroup.info:0 +msgid "Create display groups for CCK fields." +msgstr "Anzeigegruppen für CCK-Felder erstellen." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..04ad703115f1da824a347c64290ddf00381a4dcc --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.fr.po @@ -0,0 +1,110 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 19:20+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: modules/fieldgroup/fieldgroup.module:103 +msgid "Add" +msgstr "Ajouter" + +#: modules/fieldgroup/fieldgroup.module:128 +msgid "Form settings" +msgstr "Paramètres du formulaire" + +#: modules/fieldgroup/fieldgroup.module:129 +msgid "These settings apply to the group in the node editing form." +msgstr "Ces paramètres s'appliquent au groupe dans le formulaire d'édition de nœud." + +#: modules/fieldgroup/fieldgroup.module:133 +msgid "Style" +msgstr "Style" + +#: modules/fieldgroup/fieldgroup.module:136 +msgid "always open" +msgstr "toujours déplié" + +#: modules/fieldgroup/fieldgroup.module:137 +msgid "collapsible" +msgstr "repliable" + +#: modules/fieldgroup/fieldgroup.module:138 +msgid "collapsed" +msgstr "replié" + +#: modules/fieldgroup/fieldgroup.module:146 +msgid "Instructions to present to the user on the editing form." +msgstr "Instructions à présenter à l'utilisateur dans le formulaire d'édition." + +#: modules/fieldgroup/fieldgroup.module:151 +msgid "Display settings" +msgstr "Paramètres d'affichage" + +#: modules/fieldgroup/fieldgroup.module:152 +msgid "These settings apply to the group on node display." +msgstr "Ces paramètres s'appliquent au groupe à l'affichage du nœud." + +#: modules/fieldgroup/fieldgroup.module:159 +msgid "A description of the group." +msgstr "Description du groupe." + +#: modules/fieldgroup/fieldgroup.module:194 +msgid "The group name %name already exists." +msgstr "Le nom de groupe '%name' existe déjà." + +#: modules/fieldgroup/fieldgroup.module:198 +msgid "The group name %name is invalid." +msgstr "Le nom de groupe '%name' est invalide." + +#: modules/fieldgroup/fieldgroup.module:233 +msgid "Are you sure you want to remove the group %label?" +msgstr "Êtes-vous sûr(e) de vouloir supprimer le groupe '%label' ?" + +#: modules/fieldgroup/fieldgroup.module:235 +msgid "This action cannot be undone." +msgstr "Cette action est irréversible." + +#: modules/fieldgroup/fieldgroup.module:244 +msgid "The group %group_name has been removed." +msgstr "Le groupe '%group_name' a été supprimé." + +#: modules/fieldgroup/fieldgroup.module:347 +msgid "Display in group" +msgstr "Afficher dans le groupe" + +#: modules/fieldgroup/fieldgroup.module:350 +msgid "Select a group, in which the field will be displayed on the editing form." +msgstr "Choisissez un groupe dans lequel apparaîtra le champ dans le formulaire d'édition." + +#: modules/fieldgroup/fieldgroup.module:29 +msgid "Add group" +msgstr "Ajouter un groupe" + +#: modules/fieldgroup/fieldgroup.module:37;44 +msgid "Edit group" +msgstr "Éditer le groupe" + +#: modules/fieldgroup/fieldgroup.module:0 +msgid "fieldgroup" +msgstr "fieldgroup" + +#: modules/fieldgroup/fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "Fieldgroup" + +#: modules/fieldgroup/fieldgroup.info:0 +msgid "Create field groups for CCK fields." +msgstr "Créer des groupes de champs pour des champs CCK." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..551dfbc0b604555d5d0f2b30fb3a69701032532c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.hu.po @@ -0,0 +1,163 @@ +# Hungarian translation of cck (6.x-2.0-rc10) +# Copyright (c) 2008 by the Hungarian translation team +# Generated from files: +# fieldgroup.module,v 1.79.2.34 2008/10/06 15:11:39 karens +# fieldgroup.panels.inc,v 1.1.2.4 2008/10/06 17:21:51 karens +# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens +# +msgid "" +msgstr "" +"Project-Id-Version: cck (6.x-2.0-rc10)\n" +"POT-Creation-Date: 2008-10-31 12:16-0500\n" +"PO-Revision-Date: 2008-10-26 16:40-0500\n" +"Last-Translator: Balogh Zoltán\n" +"Language-Team: Drupal.hu Fordítói Csapat <forditas [at] drupal.hu>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: modules/fieldgroup/fieldgroup.module:196 +msgid "This action cannot be undone." +msgstr "Ez a művelet nem visszavonható." + +#: modules/fieldgroup/fieldgroup.module:254 +msgid "none" +msgstr "nincs" + +#: modules/fieldgroup/fieldgroup.module:126 +msgid "Style" +msgstr "Stílus" + +#: modules/fieldgroup/fieldgroup.panels.inc:10,66 +msgid "Content fieldgroup" +msgstr "Tartalom mezőcsoport" + +#: modules/fieldgroup/fieldgroup.panels.inc:47 +msgid "Content fieldgroup content goes here." +msgstr "Tartalom mezőcsoport tartalma jön ide." + +#: modules/fieldgroup/fieldgroup.panels.inc:69 +msgid "All fields from a fieldgroup on the referenced node." +msgstr "Minden mező a mezőcsoportból a hivatkozott tartalmon." + +#: modules/fieldgroup/fieldgroup.panels.inc:90 +msgid "@group_label (@group_type_name)" +msgstr "@group_label (@group_type_name)" + +#: modules/fieldgroup/fieldgroup.panels.inc:108 +msgid "" +"Text to display if group has no data. Note that title will not display " +"unless overridden." +msgstr "" +"Megjelenítendő szöveg, ha a csoportnak nincs adata. A cím nem " +"jelenik meg, ha nincs felülírva." + +#: modules/fieldgroup/fieldgroup.panels.inc:123 +msgid "\"@s\" fieldgroup @name" +msgstr "„@s” mezőcsoport @name" + +#: modules/fieldgroup/fieldgroup.module:121 +msgid "Form settings" +msgstr "Űrlap beállításai" + +#: modules/fieldgroup/fieldgroup.module:122 +msgid "These settings apply to the group in the node editing form." +msgstr "" +"Ezek a beállítások lesznek értelmezve a csoportra a " +"tartalomszerkesztő űrlapon." + +#: modules/fieldgroup/fieldgroup.module:129 +msgid "always open" +msgstr "mindig nyitott" + +#: modules/fieldgroup/fieldgroup.module:130 +msgid "collapsible" +msgstr "összecsukható" + +#: modules/fieldgroup/fieldgroup.module:131 +msgid "collapsed" +msgstr "összecsukott" + +#: modules/fieldgroup/fieldgroup.module:139 +msgid "Instructions to present to the user on the editing form." +msgstr "Az űrlap szerkesztésekor megjelenő útmutató." + +#: modules/fieldgroup/fieldgroup.module:144 +msgid "Display settings" +msgstr "Megjelenítési beállítások" + +#: modules/fieldgroup/fieldgroup.module:145 +msgid "These settings apply to the group on node display." +msgstr "" +"Ezek a beállítások lesznek értelmezve a csoportra a tartalom " +"megjelenítésekor." + +#: modules/fieldgroup/fieldgroup.module:152 +msgid "A description of the group." +msgstr "A csoport leírása." + +#: modules/fieldgroup/fieldgroup.module:194 +msgid "Are you sure you want to remove the group %label?" +msgstr "%label csoport biztosan törölhető?" + +#: modules/fieldgroup/fieldgroup.module:205 +msgid "The group %group_name has been removed." +msgstr "%group_name csoport törölve lett." + +#: modules/fieldgroup/fieldgroup.module:347 +msgid "You need to provide a label." +msgstr "Meg kell adni egy címkét." + +#: modules/fieldgroup/fieldgroup.module:352 +msgid "You need to provide a group name." +msgstr "Meg kell adni a csoport nevét." + +#: modules/fieldgroup/fieldgroup.module:366 +msgid "" +"The group name %group_name is invalid. The name must include only " +"lowercase unaccentuated letters, numbers, and underscores." +msgstr "" +"%group_name csoportnév érvénytelen. A név csak ékezet nélküli " +"kisbetűket, számokat és aláhúzásjeleket tartalmazhat." + +#: modules/fieldgroup/fieldgroup.module:369 +msgid "" +"The group name %group_name is too long. The name is limited to 32 " +"characters, including the 'group_' prefix." +msgstr "" +"%group_name csoportnév túl hosszú. A név csak 32 karakter hosszú " +"lehet, beleértve a „group_” előtagot is." + +#: modules/fieldgroup/fieldgroup.module:381 +msgid "The group name %group_name already exists." +msgstr "%group_name nevű csoport már létezik." + +#: modules/fieldgroup/fieldgroup.module:400,403 +msgid "Add new group:" +msgstr "Új csoport hozzáadása:" + +#: modules/fieldgroup/fieldgroup.module:418 +msgid "Add new group: you need to provide a label." +msgstr "Új csoport hozzáadása: meg kell adni egy címkét." + +#: modules/fieldgroup/fieldgroup.module:419 +msgid "Add new group: you need to provide a group name." +msgstr "Új csoport hozzáadása: meg kell adni a csoport nevét." + +#: modules/fieldgroup/fieldgroup.module:622 +msgid "Standard group" +msgstr "Alapvető csoport" + +#: modules/fieldgroup/fieldgroup.module:39,46 +msgid "Edit group" +msgstr "Csoport szerkesztése" + +#: modules/fieldgroup/fieldgroup.module:0 +msgid "fieldgroup" +msgstr "mezőcsoport" + +#: modules/fieldgroup/fieldgroup.info:0 +msgid "Create display groups for CCK fields." +msgstr "Csoportokat hoz létre a CCK mezők számára." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.nl.po new file mode 100644 index 0000000000000000000000000000000000000000..51f892d58fabd91de2abfbb37f79464c01b6b6d2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.nl.po @@ -0,0 +1,192 @@ +# $Id$ +# +# Dutch translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched +# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens +# fieldgroup.module,v 1.79.2.45 2009/02/28 23:56:17 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-03 14:25+0200\n" +"PO-Revision-Date: 2009-06-03 14:25+0200\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: Dutch <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: fieldgroup.panels.inc:10;27 +msgid "Content fieldgroup" +msgstr "Inhoudveldgroep" + +#: fieldgroup.panels.inc:30 +msgid "All fields from a fieldgroup on the referenced node." +msgstr "Alle velden van een veldgroep op de gerefereerde node." + +#: fieldgroup.panels.inc:31 +msgid "Node" +msgstr "Node" + +#: fieldgroup.panels.inc:32 +msgid "Node context" +msgstr "Node context" + +#: fieldgroup.panels.inc:91 +msgid "@group_label (@group_type_name)" +msgstr "@group_label (@group_type_name)" + +#: fieldgroup.panels.inc:102 fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "Veldgroep" + +#: fieldgroup.panels.inc:112 +msgid "Text to display if group has no data. Note that title will not display unless overridden." +msgstr "" +"Tekst om weer te geven als de groep geen data heeft. Merk op dat de " +"titel niet zal worden getoond tenzij anders ingesteld." + +#: fieldgroup.panels.inc:128 +msgid "\"@s\" fieldgroup @name" +msgstr "\"@s\" veldgroep @name" + +#: fieldgroup.module:111 +msgid "Label" +msgstr "Label" + +#: fieldgroup.module:124 +msgid "Form settings" +msgstr "Formulierinstellingen" + +#: fieldgroup.module:125 +msgid "These settings apply to the group in the node editing form." +msgstr "Deze instellingen zijn voor de groep in het node-bewerkformulier." + +#: fieldgroup.module:129 +msgid "Style" +msgstr "Stijl" + +#: fieldgroup.module:132 +msgid "always open" +msgstr "altijd open" + +#: fieldgroup.module:133 +msgid "collapsible" +msgstr "uitklapbaar" + +#: fieldgroup.module:134 +msgid "collapsed" +msgstr "uitgeklapt" + +#: fieldgroup.module:139 +msgid "Help text" +msgstr "Helptekst" + +#: fieldgroup.module:142 +msgid "Instructions to present to the user on the editing form." +msgstr "Instructies om aan de gebruiker te tonen bij het bewerkformulier." + +#: fieldgroup.module:147 +msgid "Display settings" +msgstr "Weergaveinstellingen" + +#: fieldgroup.module:148 +msgid "These settings apply to the group on node display." +msgstr "Deze instellingen zijn voor de groep van de node-weergave." + +#: fieldgroup.module:152 +msgid "Description" +msgstr "Beschrijving" + +#: fieldgroup.module:155 +msgid "A description of the group." +msgstr "Een beschrijving van de groep" + +#: fieldgroup.module:171;335 +msgid "Save" +msgstr "Opslaan" + +#: fieldgroup.module:200 +msgid "Are you sure you want to remove the group %label?" +msgstr "Weet je zeker dat je de groep %label wilt verwijderen?" + +#: fieldgroup.module:202 +msgid "This action cannot be undone." +msgstr "Deze actie kan niet ongedaan worden gemaakt." + +#: fieldgroup.module:203 +msgid "Remove" +msgstr "Verwijderen" + +#: fieldgroup.module:203 +msgid "Cancel" +msgstr "Annuleren" + +#: fieldgroup.module:211 +msgid "The group %group_name has been removed." +msgstr "De groep %group is verwijderd." + +#: fieldgroup.module:260 +msgid "none" +msgstr "geen" + +#: fieldgroup.module:353 +msgid "You need to provide a label." +msgstr "Je moet een label opgeven." + +#: fieldgroup.module:358 +msgid "You need to provide a group name." +msgstr "Je moet een groepnaam opgeven." + +#: fieldgroup.module:372 +msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "" +"De groepnaam %group_name in niet toegestaan. De naam mag alleen kleine " +"alfanumerieke karakters en underscores bevatten." + +#: fieldgroup.module:375 +msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix." +msgstr "" +"De groepnaam %group_name is te lang. De naam mag niet langer zijn dan " +"32 karakters inclusief 'group_'-voorvoegsel." + +#: fieldgroup.module:381 +msgid "The group name %group_name already exists." +msgstr "De groepnaam %group_name bestaat al." + +#: fieldgroup.module:400;403 +msgid "Add new group:" +msgstr "Voeg nieuwe groep toe:" + +#: fieldgroup.module:418 +msgid "Add new group: you need to provide a label." +msgstr "Voeg een nieuwe groep toe: je moet een label opgeven." + +#: fieldgroup.module:419 +msgid "Add new group: you need to provide a group name." +msgstr "Voeg nieuwe groep toe: je moet een groepnaam opgeven." + +#: fieldgroup.module:648 +msgid "Standard group" +msgstr "Standaardgroep" + +#: fieldgroup.module:39;46 +msgid "Edit group" +msgstr "Bewerk groep" + +#: fieldgroup.module:0 +msgid "fieldgroup" +msgstr "veldgroep" + +#: fieldgroup.info:0 +msgid "Create display groups for CCK fields." +msgstr "Maak weergavegroepen voor CCK-velden." + +#: fieldgroup.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.pot new file mode 100644 index 0000000000000000000000000000000000000000..167a0ed869ad041e0972e971551bbc6dfe2c2f10 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.pot @@ -0,0 +1,142 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-fieldgroup) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched +# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens +# fieldgroup.module,v 1.79.2.48 2009/04/29 20:51:52 karens +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/fieldgroup/fieldgroup.panels.inc:30 +msgid "All fields from a fieldgroup on the referenced node." +msgstr "" + +#: modules/fieldgroup/fieldgroup.panels.inc:32 +msgid "Node context" +msgstr "" + +#: modules/fieldgroup/fieldgroup.panels.inc:91 +msgid "@group_label (@group_type_name)" +msgstr "" + +#: modules/fieldgroup/fieldgroup.panels.inc:102 modules/fieldgroup/fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "" + +#: modules/fieldgroup/fieldgroup.panels.inc:128 +msgid "\"@s\" fieldgroup @name" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:130 +msgid "Form settings" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:131 +msgid "These settings apply to the group in the node editing form." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:135 +msgid "Style" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:138 +msgid "always open" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:139 +msgid "collapsible" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:140 +msgid "collapsed" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:148 +msgid "Instructions to present to the user on the editing form." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:153 +msgid "Display settings" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:154 +msgid "These settings apply to the group on node display." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:161 +msgid "A description of the group." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:206 +msgid "Are you sure you want to remove the group %label?" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:208 +msgid "This action cannot be undone." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:217 +msgid "The group %group_name has been removed." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:359 +msgid "You need to provide a label." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:364 +msgid "You need to provide a group name." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:378 +msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:381 +msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:387 +msgid "The group name %group_name already exists." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:406;409 +msgid "Add new group:" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:424 +msgid "Add new group: you need to provide a label." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:425 +msgid "Add new group: you need to provide a group name." +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:654 +msgid "Standard group" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:45;52 +msgid "Edit group" +msgstr "" + +#: modules/fieldgroup/fieldgroup.module:0 +msgid "fieldgroup" +msgstr "" + +#: modules/fieldgroup/fieldgroup.info:0 +msgid "Create display groups for CCK fields." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..c2fb9c3ea4fdc460aed01a3625145cdc200ed377 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.sv.po @@ -0,0 +1,204 @@ +# $Id$ +# +# Swedish translation of Drupal (fieldgroup) +# Generated from files: +# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched +# content_fieldgroup.inc,v 1.1.2.1 2009/04/29 18:34:46 karens +# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens +# fieldgroup.module,v 1.79.2.48 2009/04/29 20:51:52 karens +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Fieldgroup 6.x\n" +"POT-Creation-Date: 2009-05-27 13:16+0200\n" +"PO-Revision-Date: 2009-05-27 13:39+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: fieldgroup.panels.inc:10;27 +#: panels/content_types/content_fieldgroup.inc:14 +msgid "Content fieldgroup" +msgstr "Fältgrupp för innehåll" + +#: fieldgroup.panels.inc:30 +msgid "All fields from a fieldgroup on the referenced node." +msgstr "Alla fält från en fältgrupp på den hänvisade noden." + +#: fieldgroup.panels.inc:31 +#: panels/content_types/content_fieldgroup.inc:43 +msgid "Node" +msgstr "Nod" + +#: fieldgroup.panels.inc:32 +msgid "Node context" +msgstr "Sammanhang för nod" + +#: fieldgroup.panels.inc:91 +msgid "@group_label (@group_type_name)" +msgstr "@group_label (@group_type_name)" + +#: fieldgroup.panels.inc:102 +#: fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "Fältgrupp" + +#: fieldgroup.panels.inc:112 +#: panels/content_types/content_fieldgroup.inc:102 +msgid "Text to display if group has no data. Note that title will not display unless overridden." +msgstr "Text att visa om gruppen inte har något innehåll. Observera att titel inte kommer att visas om det inte åsidosätts." + +#: fieldgroup.panels.inc:128 +msgid "\"@s\" fieldgroup @name" +msgstr "\"@s\" fältgrupp @name" + +#: fieldgroup.module:117 +msgid "Label" +msgstr "Etikett" + +#: fieldgroup.module:130 +msgid "Form settings" +msgstr "Inställningar för formulär" + +#: fieldgroup.module:131 +msgid "These settings apply to the group in the node editing form." +msgstr "Dessa inställningar gäller för gruppen i redigeringsformuläret för noden." + +#: fieldgroup.module:135 +msgid "Style" +msgstr "Stil" + +#: fieldgroup.module:138 +msgid "always open" +msgstr "alltid utfälld" + +#: fieldgroup.module:139 +msgid "collapsible" +msgstr "hopfällbar" + +#: fieldgroup.module:140 +msgid "collapsed" +msgstr "hopfälld" + +#: fieldgroup.module:145 +msgid "Help text" +msgstr "Hjälptext" + +#: fieldgroup.module:148 +msgid "Instructions to present to the user on the editing form." +msgstr "Instruktioner som visas för användaren på redigeringsformuläret." + +#: fieldgroup.module:153 +msgid "Display settings" +msgstr "Inställningar för visning" + +#: fieldgroup.module:154 +msgid "These settings apply to the group on node display." +msgstr "Dessa inställningar gäller för gruppen på visningen av noden." + +#: fieldgroup.module:158 +msgid "Description" +msgstr "Beskrivning" + +#: fieldgroup.module:161 +msgid "A description of the group." +msgstr "En beskrivning av gruppen." + +#: fieldgroup.module:177;341 +msgid "Save" +msgstr "Spara" + +#: fieldgroup.module:206 +msgid "Are you sure you want to remove the group %label?" +msgstr "Är du säker på att du vill ta bort gruppen %label?" + +#: fieldgroup.module:208 +msgid "This action cannot be undone." +msgstr "Denna åtgärd kan inte ångras." + +#: fieldgroup.module:209 +msgid "Remove" +msgstr "Ta bort" + +#: fieldgroup.module:209 +msgid "Cancel" +msgstr "Avbryt" + +#: fieldgroup.module:217 +msgid "The group %group_name has been removed." +msgstr "Gruppen %group_name har tagits bort." + +#: fieldgroup.module:266 +msgid "none" +msgstr "ingen" + +#: fieldgroup.module:359 +msgid "You need to provide a label." +msgstr "Du måste ange en etikett." + +#: fieldgroup.module:364 +msgid "You need to provide a group name." +msgstr "Du måste ange ett gruppnamn." + +#: fieldgroup.module:378 +msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Gruppnamnet %group_name är inte giltigt. Namnet får enbart bestå av små bokstäver som inte är accentuerade, siffor och understreck." + +#: fieldgroup.module:381 +msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix." +msgstr "Gruppnamnet %group_name är för långt. Namnet får bestå av max 32 tecken, inklusive prefixet 'group_'." + +#: fieldgroup.module:387 +msgid "The group name %group_name already exists." +msgstr "Gruppnamnet %group_name existerar redan." + +#: fieldgroup.module:406;409 +msgid "Add new group:" +msgstr "Lägg till ny grupp:" + +#: fieldgroup.module:424 +msgid "Add new group: you need to provide a label." +msgstr "Lägg till ny grupp: du måste ange en etikett." + +#: fieldgroup.module:425 +msgid "Add new group: you need to provide a group name." +msgstr "Lägg till ny grupp: du måste ange ett gruppnamn." + +#: fieldgroup.module:654 +msgid "Standard group" +msgstr "Standardgrupp" + +#: fieldgroup.module:45;52 +msgid "Edit group" +msgstr "Redigera grupp" + +#: fieldgroup.module:0 +msgid "fieldgroup" +msgstr "fältgrupp" + +#: fieldgroup.info:0 +msgid "Create display groups for CCK fields." +msgstr "Skapa visningsgrupper för fält av typen CCK." + +#: fieldgroup.info:0 +msgid "CCK" +msgstr "CCK" + +#: panels/content_types/content_fieldgroup.inc:39 +msgid "@type: (fieldgroup) @fieldgroup" +msgstr "@type: (fältgrupp) @fieldgroup" + +#: panels/content_types/content_fieldgroup.inc:42 +msgid "All fields from this fieldgroup on the referenced node." +msgstr "Alla fält från denna fältgrup på den hänvisade noden." + +#: panels/content_types/content_fieldgroup.inc:119 +msgid "\"@s\" fieldgroup (@name)" +msgstr "\"@s\" fältgrupp (@name)" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..fae42f8d58905e789f0973f22baad8807a325355 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.help.ini @@ -0,0 +1,8 @@ +; $Id$ + +[advanced help settings] +hide = TRUE + +[nodereference] +title = Nodereference field +parent = content%fields diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.html new file mode 100644 index 0000000000000000000000000000000000000000..a62e88550274a2c010e590e85e8c5df3c840fd77 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.html @@ -0,0 +1,3 @@ +<p>The Nodereference field stores the nid of a related node. The title of the related node is usually displayed as the value of this field.</p> +<p>The Nodereference field can use an autocomplete widget, or, when used with <a href="&topic:optionwidgets/optionwidgets&">Optionwidgets</a>, the available values can be presented to the end user in a drop-down select list, checkboxes, or radios.</p> +<p>A Nodereference field can be used in Views to create a <a href="&topic:views/relationship&">Relationship</a> to another node, to allow you to use any field, argument, or filter from the related node in your view. </p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.info new file mode 100644 index 0000000000000000000000000000000000000000..fa38e36af4e8a25f3aed4876b4b2d1daf764597c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.info @@ -0,0 +1,14 @@ +; $Id$ +name = Node Reference +description = Defines a field type for referencing one node from another. +dependencies[] = content +dependencies[] = text +dependencies[] = optionwidgets +package = CCK +core = 6.x +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.install new file mode 100644 index 0000000000000000000000000000000000000000..aad591ccecebf53b0a7fc4e0ab716a632819abde --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.install @@ -0,0 +1,165 @@ +<?php +// $Id$ + +/** + * @file + * Implementation of hook_install(). + */ +function nodereference_install() { + drupal_load('module', 'content'); + content_notify('install', 'nodereference'); +} + +/** + * Implementation of hook_uninstall(). + */ +function nodereference_uninstall() { + drupal_load('module', 'content'); + content_notify('uninstall', 'nodereference'); +} + +/** + * Implementation of hook_enable(). + * + * Notify content module when this module is enabled. + */ +function nodereference_enable() { + drupal_load('module', 'content'); + content_notify('enable', 'nodereference'); +} + +/** + * Implementation of hook_disable(). + * + * Notify content module when this module is disabled. + */ +function nodereference_disable() { + drupal_load('module', 'content'); + content_notify('disable', 'nodereference'); +} + +function nodereference_update_last_removed() { + return 3; +} + +/** + * All fields must allow NULL values to indicate empty fields. + */ +function nodereference_update_6000(&$sandbox) { + include_once('./'. drupal_get_path('module', 'content') .'/content.install'); + drupal_load('module', 'content'); + + $ret = array(); + + if (!isset($sandbox['progress'])) { + if ($abort = content_check_update('nodereference')) { + return $abort; + } + + // Get the latest cache values and schema. + content_clear_type_cache(TRUE, TRUE); + $types = content_types_install(); + + if (empty($types)) { + return $ret; + } + + $sandbox['fields'] = array(); + foreach ($types as $type_name => $fields) { + foreach ($fields as $field) { + if ($field['type'] == 'nodereference') { + $sandbox['fields'][] = $field; + } + } + } + + if (empty($sandbox['fields'])) { + return $ret; + } + + $sandbox['progress'] = 0; + $sandbox['visited'] = array(); + } + + $field = $sandbox['fields'][$sandbox['progress']]; + + // We only want to process a field once -- if we hit it a second time, + // that means it's its own table and it should have already been updated. + if (!in_array($field['field_name'], $sandbox['visited'])) { + $db_info = content_database_info($field); + $table = $db_info['table']; + $attributes = $db_info['columns']['nid']; + $column = $attributes['column']; + $attributes['not null'] = FALSE; + db_change_field($ret, $table, $column, $column, array('type' => 'int', 'not null' => FALSE)); + db_field_set_no_default($ret, $db_info['table'], $column); + $ret[] = update_sql("UPDATE {". $db_info['table'] ."} SET ". $column ." = NULL WHERE ". $column ." = 0"); + + $sandbox['visited'][] = $field['field_name']; + } + + $sandbox['progress']++; + $ret['#finished'] = $sandbox['progress'] / count($sandbox['fields']); + + return $ret; +} + +/** + * Create an index by node reference column for all fields. + */ +function nodereference_update_6001(&$sandbox) { + include_once('./'. drupal_get_path('module', 'content') .'/content.install'); + drupal_load('module', 'content'); + + $ret = array(); + + if (!isset($sandbox['progress'])) { + if ($abort = content_check_update('nodereference')) { + return $abort; + } + + // Get the latest cache values and schema. + content_clear_type_cache(TRUE, TRUE); + $types = content_types_install(); + + if (empty($types)) { + return $ret; + } + + $sandbox['fields'] = array(); + foreach ($types as $type_name => $fields) { + foreach ($fields as $field) { + if ($field['type'] == 'nodereference') { + $sandbox['fields'][] = $field; + } + } + } + + if (empty($sandbox['fields'])) { + return $ret; + } + + $sandbox['progress'] = 0; + $sandbox['visited'] = array(); + } + + $field = $sandbox['fields'][$sandbox['progress']]; + + // We only want to process a field once -- if we hit it a second time, + // that means it's its own table and it should have already been updated. + if (!in_array($field['field_name'], $sandbox['visited'])) { + $db_info = content_database_info($field); + $table = $db_info['table']; + $attributes = $db_info['columns']['nid']; + $column = $attributes['column']; + if (!content_db_index_exists($table, $column)) { + db_add_index($ret, $table, $column, array($column)); + } + $sandbox['visited'][] = $field['field_name']; + } + + $sandbox['progress']++; + $ret['#finished'] = $sandbox['progress'] / count($sandbox['fields']); + + return $ret; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.module new file mode 100644 index 0000000000000000000000000000000000000000..1deda511af94c12ff0dcfb758a9cce5ba6b0c97d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.module @@ -0,0 +1,1054 @@ +<?php +// $Id$ + +/** + * @file + * Defines a field type for referencing one node from another. + */ + +/** + * Implementation of hook_menu(). + */ +function nodereference_menu() { + $items = array(); + $items['nodereference/autocomplete'] = array( + 'title' => 'Nodereference autocomplete', + 'page callback' => 'nodereference_autocomplete', + 'access callback' => 'nodereference_autocomplete_access', + 'access arguments' => array(2), + 'type' => MENU_CALLBACK + ); + return $items; +} + +/** + * Implementation of hook_theme(). + */ +function nodereference_theme() { + return array( + 'nodereference_select' => array( + 'arguments' => array('element' => NULL), + ), + 'nodereference_buttons' => array( + 'arguments' => array('element' => NULL), + ), + 'nodereference_autocomplete' => array( + 'arguments' => array('element' => NULL), + ), + 'nodereference_formatter_default' => array( + 'arguments' => array('element'), + ), + 'nodereference_formatter_plain' => array( + 'arguments' => array('element'), + ), + 'nodereference_formatter_full' => array( + 'arguments' => array('element'), + 'function' => 'theme_nodereference_formatter_full_teaser', + ), + 'nodereference_formatter_teaser' => array( + 'arguments' => array('element'), + 'function' => 'theme_nodereference_formatter_full_teaser', + ), + ); +} + +/** + * Implementaion of hook_ctools_plugin_directory(). + */ +function nodereference_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && $plugin == 'relationships') { + return 'panels/' . $plugin; + } +} + +/** + * Implementation of hook_field_info(). + */ +function nodereference_field_info() { + return array( + 'nodereference' => array( + 'label' => t('Node reference'), + 'description' => t('Store the ID of a related node as an integer value.'), +// 'content_icon' => 'icon_content_noderef.png', + ), + ); +} + +/** + * Implementation of hook_field_settings(). + */ +function nodereference_field_settings($op, $field) { + switch ($op) { + case 'form': + $form = array(); + $form['referenceable_types'] = array( + '#type' => 'checkboxes', + '#title' => t('Content types that can be referenced'), + '#multiple' => TRUE, + '#default_value' => is_array($field['referenceable_types']) ? $field['referenceable_types'] : array(), + '#options' => array_map('check_plain', node_get_types('names')), + ); + if (module_exists('views')) { + $views = array('--' => '--'); + $all_views = views_get_all_views(); + foreach ($all_views as $view) { + // Only 'node' views that have fields will work for our purpose. + if ($view->base_table == 'node' && !empty($view->display['default']->display_options['fields'])) { + if ($view->type == 'Default') { + $views[t('Default Views')][$view->name] = $view->name; + } + else { + $views[t('Existing Views')][$view->name] = $view->name; + } + } + } + + $form['advanced'] = array( + '#type' => 'fieldset', + '#title' => t('Advanced - Nodes that can be referenced (View)'), + '#collapsible' => TRUE, + '#collapsed' => !isset($field['advanced_view']) || $field['advanced_view'] == '--', + ); + if (count($views) > 1) { + $form['advanced']['advanced_view'] = array( + '#type' => 'select', + '#title' => t('View used to select the nodes'), + '#options' => $views, + '#default_value' => isset($field['advanced_view']) ? $field['advanced_view'] : '--', + '#description' => t('<p>Choose the "Views module" view that selects the nodes that can be referenced.<br />Note:</p>') . + t('<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the "Content types" settings above. Use the view\'s "filters" section instead.</li><li>Use the view\'s "fields" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view\'s "sort criteria" section to determine the order in which candidate nodes will be displayed.</li></ul>'), + ); + $form['advanced']['advanced_view_args'] = array( + '#type' => 'textfield', + '#title' => t('View arguments'), + '#default_value' => isset($field['advanced_view_args']) ? $field['advanced_view_args'] : '', + '#required' => FALSE, + '#description' => t('Provide a comma separated list of arguments to pass to the view.'), + ); + } + else { + $form['advanced']['no_view_help'] = array( + '#value' => t('<p>The list of nodes that can be referenced can be based on a "Views module" view but no appropriate views were found. <br />Note:</p>') . + t('<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the "Content types" settings above. Use the view\'s "filters" section instead.</li><li>Use the view\'s "fields" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view\'s "sort criteria" section to determine the order in which candidate nodes will be displayed.</li></ul>'), + ); + } + } + return $form; + + case 'save': + $settings = array('referenceable_types'); + if (module_exists('views')) { + $settings[] = 'advanced_view'; + $settings[] = 'advanced_view_args'; + } + return $settings; + + case 'database columns': + $columns = array( + 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'index' => TRUE), + ); + return $columns; + + case 'views data': + $data = content_views_field_views_data($field); + $db_info = content_database_info($field); + $table_alias = content_views_tablename($field); + + // Filter: swap the handler to the 'in' operator. + $data[$table_alias][$field['field_name'] .'_nid']['filter']['handler'] = 'content_handler_filter_many_to_one'; + // Argument: use node.title for summaries. + $data["node_$table_alias"]['table']['join']['node'] = array( + 'table' => 'node', + 'field' => 'nid', + 'left_table' => $table_alias, + 'left_field' => $field['field_name'] .'_nid', + ); + $data[$table_alias][$field['field_name'] .'_nid']['argument']['handler'] = 'content_handler_argument_reference'; + $data[$table_alias][$field['field_name'] .'_nid']['argument']['name table'] = "node_$table_alias"; + $data[$table_alias][$field['field_name'] .'_nid']['argument']['name field'] = 'title'; + // Relationship: add a relationship for related node. + $data[$table_alias][$field['field_name'] .'_nid']['relationship'] = array( + 'base' => 'node', + 'field' => $db_info['columns']['nid']['column'], + 'handler' => 'content_handler_relationship', + 'label' => t($field['widget']['label']), + 'content_field_name' => $field['field_name'], + ); + return $data; + } +} + +/** + * Implementation of hook_field(). + */ +function nodereference_field($op, &$node, $field, &$items, $teaser, $page) { + static $sanitized_nodes = array(); + + switch ($op) { + // When preparing a translation, load any translations of existing references. + case 'prepare translation': + $addition = array(); + $addition[$field['field_name']] = array(); + if (isset($node->translation_source->$field['field_name']) && is_array($node->translation_source->$field['field_name'])) { + foreach ($node->translation_source->$field['field_name'] as $key => $reference) { + $reference_node = node_load($reference['nid']); + // Test if the referenced node type is translatable and, if so, + // load translations if the reference is not for the current language. + // We can assume the translation module is present because it invokes 'prepare translation'. + if (translation_supported_type($reference_node->type) && !empty($reference_node->language) && $reference_node->language != $node->language && $translations = translation_node_get_translations($reference_node->tnid)) { + // If there is a translation for the current language, use it. + $addition[$field['field_name']][] = array( + 'nid' => isset($translations[$node->language]) ? $translations[$node->language]->nid : $reference['nid'], + ); + } + } + } + return $addition; + + case 'validate': + // Extract nids to check. + $ids = array(); + foreach ($items as $delta => $item) { + if (is_array($item) && !empty($item['nid'])) { + if (is_numeric($item['nid'])) { + $ids[] = $item['nid']; + } + else { + $error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; + if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); + form_set_error($error_element, t("%name: invalid input.", array('%name' => t($field['widget']['label'])))); + } + } + } + // Prevent performance hog if there are no ids to check. + if ($ids) { + $refs = _nodereference_potential_references($field, '', NULL, $ids); + foreach ($items as $delta => $item) { + if (is_array($item)) { + $error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; + if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); + if (!empty($item['nid']) && !isset($refs[$item['nid']])) { + form_set_error($error_element, t("%name: this post can't be referenced.", array('%name' => t($field['widget']['label'])))); + } + } + } + } + return $items; + + case 'sanitize': + // We can't just check the node is 'referenceable', because Views-mode + // could rely on 'current user' (at edit time). + + // Extract nids to check. + $ids = array(); + foreach ($items as $delta => $item) { + if (is_array($item)) { + // Default to 'non accessible'. + $items[$delta]['safe'] = array(); + if (!empty($item['nid']) && is_numeric($item['nid'])) { + $ids[] = $item['nid']; + } + } + } + if ($ids) { + // Load information about nids that we haven't already loaded during + // this page request. + $missing_ids = array_diff($ids, array_keys($sanitized_nodes)); + if (!empty($missing_ids)) { + $where = array('n.nid in ('. db_placeholders($missing_ids) . ')'); + if (!user_access('administer nodes')) { + $where[] = 'n.status = 1'; + } + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.status FROM {node} n WHERE '. implode(' AND ', $where)), $missing_ids); + while ($row = db_fetch_array($result)) { + $sanitized_nodes[$row['nid']] = $row; + } + } + foreach ($items as $delta => $item) { + if (is_array($item) && !empty($item['nid']) && isset($sanitized_nodes[$item['nid']])) { + $items[$delta]['safe'] = $sanitized_nodes[$item['nid']]; + } + } + } + return $items; + } +} + +/** + * Implementation of hook_content_is_empty(). + */ +function nodereference_content_is_empty($item, $field) { + if (empty($item['nid'])) { + return TRUE; + } + return FALSE; +} + +/** + * Implementation of hook_field_formatter_info(). + */ +function nodereference_field_formatter_info() { + return array( + 'default' => array( + 'label' => t('Title (link)'), + 'field types' => array('nodereference'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + 'plain' => array( + 'label' => t('Title (no link)'), + 'field types' => array('nodereference'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + 'full' => array( + 'label' => t('Full node'), + 'field types' => array('nodereference'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + 'teaser' => array( + 'label' => t('Teaser'), + 'field types' => array('nodereference'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + ); +} + +/** + * Theme function for 'default' nodereference field formatter. + */ +function theme_nodereference_formatter_default($element) { + $output = ''; + if (!empty($element['#item']['safe']['nid'])) { + $output = l($element['#item']['safe']['title'], 'node/'. $element['#item']['safe']['nid']); + if (!$element['#item']['safe']['status']) { + $output = '<span class="node-unpublished"> '. t('(Unpublished)') ." $output</span>"; + } + } + return $output; +} + +/** + * Theme function for 'plain' nodereference field formatter. + */ +function theme_nodereference_formatter_plain($element) { + $output = ''; + if (!empty($element['#item']['safe']['nid'])) { + $output = check_plain($element['#item']['safe']['title']); + if (!$element['#item']['safe']['status']) { + $output = '<span class="node-unpublished"> '. t('(Unpublished)') ." $output</span>"; + } + } + return $output; +} + +/** + * Proxy theme function for 'full' and 'teaser' nodereference field formatters. + */ +function theme_nodereference_formatter_full_teaser($element) { + static $recursion_queue = array(); + $output = ''; + if (!empty($element['#item']['safe']['nid'])) { + $nid = $element['#item']['safe']['nid']; + $node = $element['#node']; + $field = content_fields($element['#field_name'], $element['#type_name']); + // If no 'referencing node' is set, we are starting a new 'reference thread' + if (!isset($node->referencing_node)) { + $recursion_queue = array(); + } + $recursion_queue[] = $node->nid; + if (in_array($nid, $recursion_queue)) { + // Prevent infinite recursion caused by reference cycles: + // if the node has already been rendered earlier in this 'thread', + // we fall back to 'default' (node title) formatter. + return theme('nodereference_formatter_default', $element); + } + if ($referenced_node = node_load($nid)) { + $referenced_node->referencing_node = $node; + $referenced_node->referencing_field = $field; + $output = node_view($referenced_node, $element['#formatter'] == 'teaser'); + } + } + return $output; +} + +/** + * Helper function for formatters. + * + * Store node titles collected in the curent request. + */ +function _nodereference_titles($nid, $known_title = NULL) { + static $titles = array(); + if (!isset($titles[$nid])) { + $title = $known_title ? $known_title : db_result(db_query(db_rewrite_sql("SELECT n.title FROM {node} n WHERE n.nid=%d"), $nid)); + $titles[$nid] = $title ? $title : ''; + } + return $titles[$nid]; +} + +/** + * Implementation of hook_widget_info(). + * + * We need custom handling of multiple values for the nodereference_select + * widget because we need to combine them into a options list rather + * than display multiple elements. + * + * We will use the content module's default handling for default value. + * + * Callbacks can be omitted if default handing is used. + * They're included here just so this module can be used + * as an example for custom modules that might do things + * differently. + */ +function nodereference_widget_info() { + return array( + 'nodereference_select' => array( + 'label' => t('Select list'), + 'field types' => array('nodereference'), + 'multiple values' => CONTENT_HANDLE_MODULE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + 'nodereference_buttons' => array( + 'label' => t('Check boxes/radio buttons'), + 'field types' => array('nodereference'), + 'multiple values' => CONTENT_HANDLE_MODULE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + 'nodereference_autocomplete' => array( + 'label' => t('Autocomplete text field'), + 'field types' => array('nodereference'), + 'multiple values' => CONTENT_HANDLE_CORE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + ); +} + +/** + * Implementation of FAPI hook_elements(). + * + * Any FAPI callbacks needed for individual widgets can be declared here, + * and the element will be passed to those callbacks for processing. + * + * Drupal will automatically theme the element using a theme with + * the same name as the hook_elements key. + * + * Autocomplete_path is not used by text_widget but other widgets can use it + * (see nodereference and userreference). + */ +function nodereference_elements() { + return array( + 'nodereference_select' => array( + '#input' => TRUE, + '#columns' => array('uid'), '#delta' => 0, + '#process' => array('nodereference_select_process'), + ), + 'nodereference_buttons' => array( + '#input' => TRUE, + '#columns' => array('uid'), '#delta' => 0, + '#process' => array('nodereference_buttons_process'), + ), + 'nodereference_autocomplete' => array( + '#input' => TRUE, + '#columns' => array('name'), '#delta' => 0, + '#process' => array('nodereference_autocomplete_process'), + '#autocomplete_path' => FALSE, + ), + ); +} + +/** + * Implementation of hook_widget_settings(). + */ +function nodereference_widget_settings($op, $widget) { + switch ($op) { + case 'form': + $form = array(); + $match = isset($widget['autocomplete_match']) ? $widget['autocomplete_match'] : 'contains'; + $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; + if ($widget['type'] == 'nodereference_autocomplete') { + $form['autocomplete_match'] = array( + '#type' => 'select', + '#title' => t('Autocomplete matching'), + '#default_value' => $match, + '#options' => array( + 'starts_with' => t('Starts with'), + 'contains' => t('Contains'), + ), + '#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes.'), + ); + $form['size'] = array( + '#type' => 'textfield', + '#title' => t('Size of textfield'), + '#default_value' => $size, + '#element_validate' => array('_element_validate_integer_positive'), + '#required' => TRUE, + ); + } + else { + $form['autocomplete_match'] = array('#type' => 'hidden', '#value' => $match); + $form['size'] = array('#type' => 'hidden', '#value' => $size); + } + return $form; + + case 'save': + return array('autocomplete_match', 'size'); + } +} + +/** + * Implementation of hook_widget(). + * + * Attach a single form element to the form. It will be built out and + * validated in the callback(s) listed in hook_elements. We build it + * out in the callbacks rather than here in hook_widget so it can be + * plugged into any module that can provide it with valid + * $field information. + * + * Content module will set the weight, field name and delta values + * for each form element. This is a change from earlier CCK versions + * where the widget managed its own multiple values. + * + * If there are multiple values for this field, the content module will + * call this function as many times as needed. + * + * @param $form + * the entire form array, $form['#node'] holds node information + * @param $form_state + * the form_state, $form_state['values'][$field['field_name']] + * holds the field's form values. + * @param $field + * the field array + * @param $items + * array of default values for this field + * @param $delta + * the order of this item in the array of subelements (0, 1, 2, etc) + * + * @return + * the form item for a single element for this field + */ +function nodereference_widget(&$form, &$form_state, $field, $items, $delta = 0) { + switch ($field['widget']['type']) { + case 'nodereference_select': + $element = array( + '#type' => 'nodereference_select', + '#default_value' => $items, + ); + break; + + case 'nodereference_buttons': + $element = array( + '#type' => 'nodereference_buttons', + '#default_value' => $items, + ); + break; + + case 'nodereference_autocomplete': + $element = array( + '#type' => 'nodereference_autocomplete', + '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL, + '#value_callback' => 'nodereference_autocomplete_value', + ); + break; + } + return $element; +} + +/** + * Value for a nodereference autocomplete element. + * + * Substitute in the node title for the node nid. + */ +function nodereference_autocomplete_value($element, $edit = FALSE) { + $field_key = $element['#columns'][0]; + if (!empty($element['#default_value'][$field_key])) { + $nid = $element['#default_value'][$field_key]; + $value = db_result(db_query(db_rewrite_sql('SELECT n.title FROM {node} n WHERE n.nid = %d'), $nid)); + $value .= ' [nid:'. $nid .']'; + return array($field_key => $value); + } + return array($field_key => NULL); +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function nodereference_select_process($element, $edit, $form_state, $form) { + // The nodereference_select widget doesn't need to create its own + // element, it can wrap around the optionwidgets_select element. + // This will create a new, nested instance of the field. + // Add a validation step where the value can be unwrapped. + $field_key = $element['#columns'][0]; + $element[$field_key] = array( + '#type' => 'optionwidgets_select', + '#default_value' => isset($element['#value']) ? $element['#value'] : '', + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#required' => $element['#required'], + '#description' => $element['#description'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + if (empty($element[$field_key]['#element_validate'])) { + $element[$field_key]['#element_validate'] = array(); + } + array_unshift($element[$field_key]['#element_validate'], 'nodereference_optionwidgets_validate'); + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function nodereference_buttons_process($element, $edit, $form_state, $form) { + // The nodereference_select widget doesn't need to create its own + // element, it can wrap around the optionwidgets_select element. + // This will create a new, nested instance of the field. + // Add a validation step where the value can be unwrapped. + $field_key = $element['#columns'][0]; + $element[$field_key] = array( + '#type' => 'optionwidgets_buttons', + '#default_value' => isset($element['#value']) ? $element['#value'] : '', + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#required' => $element['#required'], + '#description' => $element['#description'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + if (empty($element[$field_key]['#element_validate'])) { + $element[$field_key]['#element_validate'] = array(); + } + array_unshift($element[$field_key]['#element_validate'], 'nodereference_optionwidgets_validate'); + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + */ +function nodereference_autocomplete_process($element, $edit, $form_state, $form) { + + // The nodereference autocomplete widget doesn't need to create its own + // element, it can wrap around the text_textfield element and add an autocomplete + // path and some extra processing to it. + // Add a validation step where the value can be unwrapped. + $field_key = $element['#columns'][0]; + + $element[$field_key] = array( + '#type' => 'text_textfield', + '#default_value' => isset($element['#value']) ? $element['#value'] : '', + '#autocomplete_path' => 'nodereference/autocomplete/'. $element['#field_name'], + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#required' => $element['#required'], + '#description' => $element['#description'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + if (empty($element[$field_key]['#element_validate'])) { + $element[$field_key]['#element_validate'] = array(); + } + array_unshift($element[$field_key]['#element_validate'], 'nodereference_autocomplete_validate'); + + // Used so that hook_field('validate') knows where to flag an error. + $element['_error_element'] = array( + '#type' => 'value', + // Wrapping the element around a text_textfield element creates a + // nested element, so the final id will look like 'field-name-0-nid-nid'. + '#value' => implode('][', array_merge($element['#parents'], array($field_key, $field_key))), + ); + return $element; +} + +/** + * Validate a select/buttons element. + * + * Remove the wrapper layer and set the right element's value. + * We don't know exactly where this element is, so we drill down + * through the element until we get to our key. + * + * We use $form_state['values'] instead of $element['#value'] + * to be sure we have the most accurate value when other modules + * like optionwidgets are using #element_validate to alter the value. + */ +function nodereference_optionwidgets_validate($element, &$form_state) { + $field_key = $element['#columns'][0]; + + $value = $form_state['values']; + $new_parents = array(); + foreach ($element['#parents'] as $parent) { + $value = $value[$parent]; + // Use === to be sure we get right results if parent is a zero (delta) value. + if ($parent === $field_key) { + $element['#parents'] = $new_parents; + form_set_value($element, $value, $form_state); + break; + } + $new_parents[] = $parent; + } +} + +/** + * Validate an autocomplete element. + * + * Remove the wrapper layer and set the right element's value. + * This will move the nested value at 'field-name-0-nid-nid' + * back to its original location, 'field-name-0-nid'. + */ +function nodereference_autocomplete_validate($element, &$form_state) { + $field_name = $element['#field_name']; + $type_name = $element['#type_name']; + $field = content_fields($field_name, $type_name); + $field_key = $element['#columns'][0]; + $delta = $element['#delta']; + $value = $element['#value'][$field_key]; + $nid = NULL; + if (!empty($value)) { + preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $value, $matches); + if (!empty($matches)) { + // Explicit [nid:n]. + list(, $title, $nid) = $matches; + if (!empty($title) && ($n = node_load($nid)) && trim($title) != trim($n->title)) { + form_error($element[$field_key], t('%name: title mismatch. Please check your selection.', array('%name' => t($field['widget']['label'])))); + } + } + else { + // No explicit nid. + $reference = _nodereference_potential_references($field, $value, 'equals', NULL, 1); + if (empty($reference)) { + form_error($element[$field_key], t('%name: found no valid post with that title.', array('%name' => t($field['widget']['label'])))); + } + else { + // 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($reference); + } + } + } + form_set_value($element, $nid, $form_state); +} + +/** + * Implementation of hook_allowed_values(). + */ +function nodereference_allowed_values($field) { + $references = _nodereference_potential_references($field); + + $options = array(); + foreach ($references as $key => $value) { + $options[$key] = $value['rendered']; + } + + return $options; +} + +/** + * Fetch an array of all candidate referenced 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 description. + * @param $string + * Optional string to filter titles on (used by autocomplete). + * @param $match + * Operator to match filtered name against, can be any of: + * 'contains', 'equals', 'starts_with' + * @param $ids + * Optional node ids to lookup (the $string and $match arguments will be + * ignored). + * @param $limit + * If non-zero, limit the size of the result set. + * + * @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 _nodereference_potential_references($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { + static $results = array(); + + // Create unique id for static cache. + $cid = $field['field_name'] .':'. $match .':'. ($string !== '' ? $string : implode('-', $ids)) .':'. $limit; + if (!isset($results[$cid])) { + $references = FALSE; + if (module_exists('views') && !empty($field['advanced_view']) && $field['advanced_view'] != '--') { + $references = _nodereference_potential_references_views($field, $string, $match, $ids, $limit); + } + // If the view doesn't exist, we got FALSE, and fallback to the regular 'standard mode'. + + if ($references === FALSE) { + $references = _nodereference_potential_references_standard($field, $string, $match, $ids, $limit); + } + + // Store the results. + $results[$cid] = !empty($references) ? $references : array(); + } + + return $results[$cid]; +} + +/** + * Helper function for _nodereference_potential_references(): + * case of Views-defined referenceable nodes. + */ +function _nodereference_potential_references_views($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { + $view_name = $field['advanced_view']; + + if ($view = views_get_view($view_name)) { + // We add a display, and let it derive from the 'default' display. + // TODO: We should let the user pick a display in the fields settings - sort of requires AHAH... + $display = $view->add_display('content_references'); + $view->set_display($display); + + // TODO from merlinofchaos on IRC : arguments using summary view can defeat the style setting. + // We might also need to check if there's an argument, and set *its* style_plugin as well. + $view->display_handler->set_option('style_plugin', 'content_php_array_autocomplete'); + $view->display_handler->set_option('row_plugin', 'fields'); + // Used in content_plugin_style_php_array::render(), to get + // the 'field' to be used as title. + $view->display_handler->set_option('content_title_field', 'title'); + + // Additional options to let content_plugin_display_references::query() + // narrow the results. + $options = array( + 'table' => 'node', + 'field_string' => 'title', + 'string' => $string, + 'match' => $match, + 'field_id' => 'nid', + 'ids' => $ids, + ); + $view->display_handler->set_option('content_options', $options); + + // TODO : for consistency, a fair amount of what's below + // should be moved to content_plugin_display_references + + // Limit result set size. + $limit = isset($limit) ? $limit : 0; + $view->display_handler->set_option('items_per_page', $limit); + + // Get arguments for the view. + if (!empty($field['advanced_view_args'])) { + // TODO: Support Tokens using token.module ? + $view_args = array_map('trim', explode(',', $field['advanced_view_args'])); + } + else { + $view_args = array(); + } + + // We do need title field, so add it if not present (unlikely, but...) + $fields = $view->get_items('field', $display); + if (!isset($fields['title'])) { + $view->add_item($display, 'field', 'node', 'title'); + } + + // If not set, make all fields inline and define a separator. + $options = $view->display_handler->get_option('row_options'); + if (empty($options['inline'])) { + $options['inline'] = drupal_map_assoc(array_keys($view->get_items('field', $display))); + } + if (empty($options['separator'])) { + $options['separator'] = '-'; + } + $view->display_handler->set_option('row_options', $options); + + // Make sure the query is not cached + $view->is_cacheable = FALSE; + + // Get the results. + $result = $view->execute_display($display, $view_args); + } + else { + $result = FALSE; + } + + return $result; +} + +/** + * Helper function for _nodereference_potential_references(): + * referenceable nodes defined by content types. + */ +function _nodereference_potential_references_standard($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { + $related_types = array(); + $where = array(); + $args = array(); + + if (is_array($field['referenceable_types'])) { + foreach (array_filter($field['referenceable_types']) as $related_type) { + $related_types[] = "n.type = '%s'"; + $args[] = $related_type; + } + } + + $where[] = implode(' OR ', $related_types); + + if (!count($related_types)) { + return array(); + } + + if ($string !== '') { + $like = $GLOBALS["db_type"] == 'pgsql' ? "ILIKE" : "LIKE"; + $match_clauses = array( + 'contains' => "$like '%%%s%%'", + 'equals' => "= '%s'", + 'starts_with' => "$like '%s%%'", + ); + $where[] = 'n.title '. (isset($match_clauses[$match]) ? $match_clauses[$match] : $match_clauses['contains']); + $args[] = $string; + } + elseif ($ids) { + $where[] = 'n.nid IN (' . db_placeholders($ids) . ')'; + $args = array_merge($args, $ids); + } + + $where_clause = $where ? 'WHERE ('. implode(') AND (', $where) .')' : ''; + $sql = db_rewrite_sql("SELECT n.nid, n.title AS node_title, n.type AS node_type FROM {node} n $where_clause ORDER BY n.title, n.type"); + $result = $limit ? db_query_range($sql, $args, 0, $limit) : db_query($sql, $args); + $references = array(); + while ($node = db_fetch_object($result)) { + $references[$node->nid] = array( + 'title' => $node->node_title, + 'rendered' => check_plain($node->node_title), + ); + } + + return $references; +} + +/** + * Check access to the menu callback of the autocomplete widget. + * + * Check for both 'edit' and 'view' access in the unlikely event + * a user has edit but not view access. + */ +function nodereference_autocomplete_access($field_name) { + return user_access('access content') && ($field = content_fields($field_name)) && isset($field['field_name']) && content_access('view', $field) && content_access('edit', $field); +} + +/** + * Menu callback; Retrieve a pipe delimited string of autocomplete suggestions for existing users + */ +function nodereference_autocomplete($field_name, $string = '') { + $fields = content_fields(); + $field = $fields[$field_name]; + $match = isset($field['widget']['autocomplete_match']) ? $field['widget']['autocomplete_match'] : 'contains'; + $matches = array(); + + $references = _nodereference_potential_references($field, $string, $match, array(), 10); + foreach ($references as $id => $row) { + // Add a class wrapper for a few required CSS overrides. + $matches[$row['title'] ." [nid:$id]"] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>'; + } + drupal_json($matches); +} + +/** + * Implementation of hook_node_types. + */ +function nodereference_node_type($op, $info) { + switch ($op) { + case 'update': + // Reflect type name changes to the 'referenceable types' settings. + if (!empty($info->old_type) && $info->old_type != $info->type) { + // content.module's implementaion of hook_node_type() has already + // refreshed _content_type_info(). + $fields = content_fields(); + $rebuild = FALSE; + foreach ($fields as $field_name => $field) { + if ($field['type'] == 'nodereference' && isset($field['referenceable_types'][$info->old_type])) { + $field['referenceable_types'][$info->type] = empty($field['referenceable_types'][$info->old_type]) ? 0 : $info->type; + unset($field['referenceable_types'][$info->old_type]); + content_field_instance_update($field, FALSE); + $rebuild = TRUE; + } + } + + // Clear caches and rebuild menu only if any field has been updated. + if ($rebuild) { + content_clear_type_cache(TRUE); + menu_rebuild(); + } + } + break; + } +} + +/** + * Theme preprocess function. + * + * Allows specific node templates for nodes displayed as values of a + * nodereference field with the 'full node' / 'teaser' formatters. + */ +function nodereference_preprocess_node(&$vars) { + // The 'referencing_field' attribute of the node is added by the 'teaser' + // and 'full node' formatters. + if (!empty($vars['node']->referencing_field)) { + $node = $vars['node']; + $field = $node->referencing_field; + $vars['template_files'][] = 'node-nodereference'; + $vars['template_files'][] = 'node-nodereference-'. $field['field_name']; + $vars['template_files'][] = 'node-nodereference-'. $node->type; + $vars['template_files'][] = 'node-nodereference-'. $field['field_name'] .'-'. $node->type; + } +} + +/** + * FAPI theme for an individual elements. + * + * The textfield or select is already rendered by the + * textfield or select themes and the html output + * lives in $element['#children']. Override this theme to + * make custom changes to the output. + * + * $element['#field_name'] contains the field name + * $element['#delta] is the position of this element in the group + */ +function theme_nodereference_select($element) { + return $element['#children']; +} + +function theme_nodereference_buttons($element) { + return $element['#children']; +} + +function theme_nodereference_autocomplete($element) { + return $element['#children']; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.rules.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.rules.inc new file mode 100644 index 0000000000000000000000000000000000000000..7a9d4d537ac6715d0487ab701ed692b771938596 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.rules.inc @@ -0,0 +1,60 @@ +<?php +// $Id$ + +/** + * @file + * Provides additional rules support for nodereference fields. + */ + +/** + * Implementation of hook_rules_action_info(). + */ +function nodereference_rules_action_info() { + $info = array(); + $info['nodereference_rules_action_load'] = array( + 'label' => t('Load a referenced node'), + 'arguments' => array( + 'node' => array( + 'type' => 'node', + 'label' => t('Content containing the node reference field'), + ), + ), + 'new variables' => array( + 'referenced_node' => array( + 'type' => 'node', + 'label' => t('Referenced content'), + ), + ), + 'module' => 'CCK', + 'help' => t('Note that if the field has multiple values, only the first content node will be loaded.'), + ); + return $info; +} + +function nodereference_rules_action_load($node, $settings) { + if ($nid = $node->{$settings['field']}[0]['nid']) { + return array('referenced_node' => node_load(array('nid' => $nid))); + } +} + +function nodereference_rules_action_load_form($settings, &$form) { + $settings += array('field' => ''); + $options = content_rules_get_field_names_by_type('nodereference'); + $form['settings']['field'] = array( + '#type' => 'select', + '#title' => t('Field'), + '#default_value' => $settings['field'], + '#options' => $options, + '#required' => TRUE, + '#disabled' => empty($options), + '#description' => empty($options) ? t('There are no nodereference fields defined.') : '', + ); +} + +/** + * Helps upgrading from the workflow-ng action + * "workflow_ng_action_load_referenced_node" to the equivalent rules action. + */ +function workflow_ng_action_load_referenced_node_upgrade(&$element) { + $element['#name'] = 'nodereference_rules_action_load'; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/panels/relationships/node_from_noderef.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/panels/relationships/node_from_noderef.inc new file mode 100644 index 0000000000000000000000000000000000000000..74d47f57772fff95ab05212e8e0f98d9bbac6673 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/panels/relationships/node_from_noderef.inc @@ -0,0 +1,76 @@ +<?php +// $Id$ + +/** + * @file + * Implements the node reference relationship for Panels. + */ + +/** + * Implementation of hook_ctools_relationships(). + */ +function nodereference_node_from_noderef_ctools_relationships() { + return array( + 'title' => t('Node from reference'), + 'keyword' => 'nodereference', + 'description' => t('Adds a node from a node reference in a node context; if multiple nodes are referenced, this will get the first referenced node only.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'context' => 'nodereference_node_from_noderef_context', + 'settings form' => 'nodereference_node_from_noderef_settings_form', + 'settings form validate' => 'nodereference_node_from_noderef_settings_form_validate', + ); +} + +/** + * Return a new ctools context based on an existing context. + */ +function nodereference_node_from_noderef_context($context, $conf) { + $field = content_fields($conf['field_name']); + + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data)) { + $new_context = ctools_context_create_empty('node', NULL); + } + else if (isset($context->data->{$conf['field_name']}[0]['nid']) && ($nid = $context->data->{$conf['field_name']}[0]['nid'])) { + if ($node = node_load($nid)) { + $new_context = ctools_context_create('node', $node); + } + } + + if (!empty($new_context)) { + // Have nodereference relationships limit CCK field availability as well. + $restrictions = array_keys(array_filter($field['referenceable_types'])); + if ($restrictions) { + if (isset($new_context->restrictions['type'])) { + $new_context->restrictions['type'] = array_unique(array_merge($new_context->restrictions['type'], $restrictions)); + } + else { + $new_context->restrictions['type'] = $restrictions; + } + } + + return $new_context; + } +} + +/** + * Settings form for the ctools relationship. + */ +function nodereference_node_from_noderef_settings_form($conf) { + $options = array(); + foreach (content_fields() as $field) { + if ($field['type'] == 'nodereference') { + $options[$field['field_name']] = t($field['widget']['label']); + } + } + $form['field_name'] = array( + '#title' => t('Node reference field'), + '#type' => 'select', + '#options' => $options, + '#default_value' => isset($conf['field_name']) ? $conf['field_name'] : '', + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + + return $form; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.de.po new file mode 100644 index 0000000000000000000000000000000000000000..310bd8c77ba9a3063a807e942fef413f2eb11d22 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.de.po @@ -0,0 +1,42 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:10+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/nodereference/panels/relationships/node_from_noderef.inc:14 +msgid "Node from reference" +msgstr "Beitrag der Referenz" + +#: modules/nodereference/panels/relationships/node_from_noderef.inc:16 +msgid "Adds a node from a node reference in a node context; if multiple nodes are referenced, this will get the first referenced node only." +msgstr "" + +#: modules/nodereference/panels/relationships/node_from_noderef.inc:50 +msgid "Node reference field" +msgstr "Beitragsreferenzfeld" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.pot new file mode 100644 index 0000000000000000000000000000000000000000..123269570fcfebe414efd92b531037718b67a04f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.pot @@ -0,0 +1,31 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-nodereference-panels-relationships) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from file: node_from_noderef.inc,v 1.1.2.1 2009/06/02 12:24:03 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/nodereference/panels/relationships/node_from_noderef.inc:14 +msgid "Node from reference" +msgstr "" + +#: modules/nodereference/panels/relationships/node_from_noderef.inc:16 +msgid "Adds a node from a node reference in a node context; if multiple nodes are referenced, this will get the first referenced node only." +msgstr "" + +#: modules/nodereference/panels/relationships/node_from_noderef.inc:50 +msgid "Node reference field" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.de.po new file mode 100644 index 0000000000000000000000000000000000000000..c8df9d5471b09fb2aa3eb42f30241753edd7e8ee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.de.po @@ -0,0 +1,124 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-03-09 22:59+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/nodereference/nodereference.rules.inc:15 +msgid "Load a referenced node" +msgstr "Referenzierten Beitrag laden" + +#: modules/nodereference/nodereference.rules.inc:19 +msgid "Content containing the node reference field" +msgstr "Der Inhalt der das Beitragsreferenzfeld enthält" + +#: modules/nodereference/nodereference.rules.inc:25 +msgid "Referenced content" +msgstr "Referenzierter Inhalt" + +#: modules/nodereference/nodereference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first content node will be loaded." +msgstr "Sollte ein Feld mehrere Werte enthalten, wird nur der erste Beitrag geladen." + +#: modules/nodereference/nodereference.rules.inc:50 +msgid "There are no nodereference fields defined." +msgstr "Es sind keine Beitragsreferenzfelder vorhanden." + +#: modules/nodereference/nodereference.module:60 +msgid "Node reference" +msgstr "Beitragsreferenz" + +#: modules/nodereference/nodereference.module:61 +msgid "Store the ID of a related node as an integer value." +msgstr "Speichert die ID des zugehörigen Beitrages als ganzzahligen Wert." + +#: modules/nodereference/nodereference.module:75 +msgid "Content types that can be referenced" +msgstr "Inhaltstypen, auf die referenziert werden kann" + +#: modules/nodereference/nodereference.module:97 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Erweitert - Beiträge, auf die referenziert werden kann (Ansicht)" + +#: modules/nodereference/nodereference.module:104 +msgid "View used to select the nodes" +msgstr "Die zur Auswahl von Beiträgen verwendete Ansicht" + +#: modules/nodereference/nodereference.module:107 +#, fuzzy +msgid "<p>Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note:</p>" +msgstr "<p>Wähle die „Views-Modul“-Ansicht das die Beiträge auswählt, die Referenziert werden können.<br />Hinweis:</p>" + +#: modules/nodereference/nodereference.module:108;121 +#, fuzzy +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "<ul><li>Nur Ansichten mit Feldern werden für diesen Zweck nutzbar sein.</li><li>Dies wird die obigen Einstellungen der „Inhaltsttypen“ verwerfen. Stattdessen sollte hierfür der „Filter“-Bereich der Ansicht verwendet werden.</li><li>Um weitere Informationen über Beitragskandidaten für das Erstellungs-/Bearbeitungsformular anzuzeigen, kann das Ansichten-Feld verwendet werden.</li><li>Um die Reihenfolge der Beitragskandidaten festzulegen sollte das „Sortierkriterium“ von Ansichten verwendet werden.</li></ul>" + +#: modules/nodereference/nodereference.module:120 +msgid "<p>The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +#: modules/nodereference/nodereference.module:217 +msgid "%name: this post can't be referenced." +msgstr "%name: Dieser Beitrag kann nicht referenziert werden." + +#: modules/nodereference/nodereference.module:242 +msgid "Title (link)" +msgstr "Titel (Link)" + +#: modules/nodereference/nodereference.module:247 +msgid "Title (no link)" +msgstr "Titel (kein Link)" + +#: modules/nodereference/nodereference.module:423 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes." +msgstr "Die Methode zur Sammlung von Autovervollständigungsvorschlägen auswählen. Dabei ist zu beachten, dass <em>Enthält</em> auf Websites mit tausenden von Beiträgen große Performanceprobleme verursachen kann." + +#: modules/nodereference/nodereference.module:671 +msgid "%name: title mismatch. Please check your selection." +msgstr "%name: Der Titel ist ungültig. Bitte die Auswahl überprüfen." + +#: modules/nodereference/nodereference.module:678 +msgid "%name: found no valid post with that title." +msgstr "%name: Kein gültiger Beitrag mit diesem Titel gefunden." + +#: modules/nodereference/nodereference.module:15 +msgid "Nodereference autocomplete" +msgstr "Autovervollständigung der Beitragsreferenz" + +#: modules/nodereference/nodereference.module:0 +msgid "nodereference" +msgstr "Beitragsreferenz" + +#: modules/nodereference/nodereference.info:0 +msgid "Node Reference" +msgstr "Beitragsreferenz" + +#: modules/nodereference/nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "Definiert einen Feldtyp, um einen Beitrag von einem anderen zu referenzieren." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..8afec3675a5585f25751a31b91ab689592b32b3c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.fr.po @@ -0,0 +1,86 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 18:05+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: modules/nodereference/nodereference.module:71 +msgid "Node reference" +msgstr "Référence de nœud" + +#: modules/nodereference/nodereference.module:72 +msgid "Store the ID of a related node as an integer value." +msgstr "Enregistre l'identifiant d'un nœud associé, sous la forme d'une valeur entière." + +#: modules/nodereference/nodereference.module:90 +msgid "Content types that can be referenced" +msgstr "Types de contenu pouvant être référencés" + +#: modules/nodereference/nodereference.module:101 +msgid "Existing Views" +msgstr "Vues existantes" + +#: modules/nodereference/nodereference.module:108 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Avancé - Nœuds pouvant être référencés (Vue)" + +#: modules/nodereference/nodereference.module:114 +msgid "View used to select the nodes" +msgstr "Vue utilisée pour choisir les nœuds" + +#: modules/nodereference/nodereference.module:117 +msgid "Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note:<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "Choisissez la vue du module Views qui sélectionne les nœuds pouvant être référencés.<br />Notez que :<ul><li>seules les vues présentant des champs fonctionneront dans ce cadre </li><li>ceci effacera les paramètres de \"Types de contenus\" figurant ci-dessus. Utilisez à la place la section \"filtres\" de la vue ;</li><li>utilisez la section \"champs\" de la vue pour afficher des informations supplémentaires sur les nœuds candidats dans le formulaire de création/édition de nœud ;</li><li>utilisez la section \"critère de tri\" de la vue pour déterminer l'ordre d'affichage des nœuds candidats.</li></ul>" + +#: modules/nodereference/nodereference.module:121 +msgid "View arguments" +msgstr "Arguments de la vue" + +#: modules/nodereference/nodereference.module:124 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Fournit une liste d'arguments, séparés par des virgules, à transmettre à la vue." + +#: modules/nodereference/nodereference.module:175 +msgid "%name: This post can't be referenced." +msgstr "Champ '%name' : cette publication ne peut être référencée." + +#: modules/nodereference/nodereference.module:200 +msgid "Title (link)" +msgstr "Titre (avec lien)" + +#: modules/nodereference/nodereference.module:205 +msgid "Title (no link)" +msgstr "Titre (sans lien)" + +#: modules/nodereference/nodereference.module:518 +msgid "%name: Title mismatch. Please check your selection." +msgstr "Champ '%name' : incohérence au niveau du titre. Merci de vérifier votre sélection." + +#: modules/nodereference/nodereference.module:15 +msgid "Nodereference autocomplete" +msgstr "Auto-complètement de la référence de nœud" + +#: modules/nodereference/nodereference.module:0 +msgid "nodereference" +msgstr "nodereference" + +#: modules/nodereference/nodereference.info:0 +msgid "Node Reference" +msgstr "Node Reference" + +#: modules/nodereference/nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "Définit un type de champ qui permet d'établir des liens entre les nœuds." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..17625b2569b73c5d302295d84ec77aaea7b10aa5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.hu.po @@ -0,0 +1,123 @@ +# Hungarian translation of cck (6.x-2.0-rc10) +# Copyright (c) 2008 by the Hungarian translation team +# Generated from files: +# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# nodereference.module,v 1.138.2.38 2008/10/06 15:11:39 karens +# nodereference.info,v 1.8 2008/04/23 18:02:07 dww +# +msgid "" +msgstr "" +"Project-Id-Version: cck (6.x-2.0-rc10)\n" +"POT-Creation-Date: 2008-10-31 12:16-0500\n" +"PO-Revision-Date: 2008-10-26 16:40-0500\n" +"Last-Translator: Balogh Zoltán\n" +"Language-Team: Drupal.hu Fordítói Csapat <forditas [at] drupal.hu>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: modules/nodereference/nodereference.rules.inc:15 +msgid "Load a referenced node" +msgstr "Egy hivatkozott tartalom betöltése" + +#: modules/nodereference/nodereference.rules.inc:19 +msgid "Content containing the node reference field" +msgstr "A tartalom, amely a hivatkozó mezőt tartalmazza" + +#: modules/nodereference/nodereference.rules.inc:25 +msgid "Referenced content" +msgstr "Hivatkozott tartalom" + +#: modules/nodereference/nodereference.rules.inc:29 +msgid "" +"Note that if the field has multiple values, only the first content " +"node will be loaded." +msgstr "" +"Megjegyzés: Ha a mezőnek több értéke is lehet, akkor csak az " +"első tartalom fog betöltődni." + +#: modules/nodereference/nodereference.rules.inc:50 +msgid "There are no nodereference fields defined." +msgstr "Nincsenek tartalomra hivatkozó mezők meghatározva." + +#: modules/nodereference/nodereference.module:68 +msgid "Node reference" +msgstr "Tartalomra hivatkozás" + +#: modules/nodereference/nodereference.module:69 +msgid "Store the ID of a related node as an integer value." +msgstr "A hivatkozott tartalom azonosítójának tárolása egész számként." + +#: modules/nodereference/nodereference.module:87 +msgid "Content types that can be referenced" +msgstr "Tartalomtípusok, melyekre hivatkozni lehet" + +#: modules/nodereference/nodereference.module:110 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Haladó - tartalmak, melyekre hivatkozni lehet (Nézet)" + +#: modules/nodereference/nodereference.module:116 +msgid "View used to select the nodes" +msgstr "Nézet használata a tartalmak kiválasztásához" + +#: modules/nodereference/nodereference.module:119 +msgid "" +"Choose the \"Views module\" view that selects the nodes that can be " +"referenced.<br />Note:<ul><li>Only views that have fields will work " +"for this purpose.</li><li>This will discard the \"Content types\" " +"settings above. Use the view's \"filters\" section " +"instead.</li><li>Use the view's \"fields\" section to display " +"additional informations about candidate nodes on node creation/edition " +"form.</li><li>Use the view's \"sort criteria\" section to determine " +"the order in which candidate nodes will be displayed.</li></ul>" +msgstr "" +"A „Nézet modul” egyik nézetének kiválasztása, mely azokat a " +"tartalmakat mutatja, melyekre hivatkozni " +"lehet.<br>Megjegyzés:<ul><li>Itt csak olyan nézet működik, melynek " +"vannak mezői.</li><li>Ez felülírja a fenti „Tartalomtípusok” " +"beállítást. A nézet „szűrő” feltétele használható e " +"helyett.</li><li>A nézet „mezők” része használható arra, hogy " +"bővebb információkat jelenítsen meg a lehetséges tartalmakról a " +"szerkesztő űrlapon.</li><li>A nézet „sorrend” része " +"befolyásolja a lehetséges tartalmak megjelenítési " +"sorrendjét.</li></ul>" + +#: modules/nodereference/nodereference.module:199 +msgid "%name: this post can't be referenced." +msgstr "%name: erre a tartalomra nem lehet hivatkozni." + +#: modules/nodereference/nodereference.module:224 +msgid "Title (link)" +msgstr "Cím (hivatkozással)" + +#: modules/nodereference/nodereference.module:229 +msgid "Title (no link)" +msgstr "Cím (hivatkozás nélkül)" + +#: modules/nodereference/nodereference.module:624 +msgid "%name: title mismatch. Please check your selection." +msgstr "%name: a cím nem egyezik." + +#: modules/nodereference/nodereference.module:631 +msgid "%name: found no valid post with that title." +msgstr "%name: nincs érvényes tartalom ezzel a címmel." + +#: modules/nodereference/nodereference.module:15 +msgid "Nodereference autocomplete" +msgstr "Automatikusan kiegészülő tartalomhivatkozás" + +#: modules/nodereference/nodereference.module:0 +msgid "nodereference" +msgstr "tartalomhivatozás" + +#: modules/nodereference/nodereference.info:0 +msgid "Node Reference" +msgstr "Tartalomra hivatkozás" + +#: modules/nodereference/nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "" +"Olyan mezőtípust ad, amely a tartalomban egy másik tartalomra " +"hivatkozik." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.nl.po new file mode 100644 index 0000000000000000000000000000000000000000..514ff86fa5e7f24bdea8265c51da823121f20be0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.nl.po @@ -0,0 +1,193 @@ +# $Id$ +# +# Dutch translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# nodereference.module,v 1.138.2.50 2009/03/18 21:00:58 yched +# nodereference.info,v 1.8 2008/04/23 18:02:07 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-03 14:25+0200\n" +"PO-Revision-Date: 2009-06-03 14:25+0200\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: Dutch <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: nodereference.rules.inc:15 +msgid "Load a referenced node" +msgstr "Laad een gerefereerde node" + +#: nodereference.rules.inc:19 +msgid "Content containing the node reference field" +msgstr "Inhoud met het nodereferentieveld" + +#: nodereference.rules.inc:25 +msgid "Referenced content" +msgstr "Gerefereerde inhoud" + +#: nodereference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first content node will be loaded." +msgstr "" +"Merk op dat als het veld meerdere waardes heeft, alleen de eerste " +"inhoudnode zal worden geladen." + +#: nodereference.rules.inc:45 +msgid "Field" +msgstr "Veld" + +#: nodereference.rules.inc:50 +msgid "There are no nodereference fields defined." +msgstr "Er zijn geen nodereferentie velden." + +#: nodereference.module:60 +msgid "Node reference" +msgstr "Nodereferentie" + +#: nodereference.module:61 +msgid "Store the ID of a related node as an integer value." +msgstr "Bewaar de ID van een gerelateerde node als een integer-waarde." + +#: nodereference.module:75 +msgid "Content types that can be referenced" +msgstr "Inhoudstypes waarnaar een referentie geplaatst kan worden" + +#: nodereference.module:87 +msgid "Default Views" +msgstr "Standaard views" + +#: nodereference.module:90 +msgid "Existing Views" +msgstr "Bestaande Views" + +#: nodereference.module:97 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Geavanceerd - Nodes die kunnen worden gerefereerd (View)" + +#: nodereference.module:104 +msgid "View used to select the nodes" +msgstr "View die gebruikt wordt voor het selecteren van nodes" + +#: nodereference.module:107 +msgid "<p>Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note:</p>" +msgstr "" +"<p>Kies de \"Views module\"-view die selecteert welke nodes kunnen " +"worden gerefereerd.<br />Merk op:</p>" + +#: nodereference.module:108;121 +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "" +"<ul><li>Alleen Views met velden zullen werken voor dit " +"doel.</li><li>Dit zal de \"Inhoudstypes-\"-instellingen boven " +"negeren. Gebruik anders de view z'n \"filters\" " +"sectie.</li><li>Gebruik de view z'n \"velden\"-sectie om extra " +"informatie over gebruikers op het bewerkformulier weer te " +"geven.</li><li>Gebruik de view z'n \"sorteercriteria\"-sectie om de " +"volgorde te bepalen waarin gebruikers worden weergegeven.</li></ul>" + +#: nodereference.module:112 +msgid "View arguments" +msgstr "Bekijk argumenten" + +#: nodereference.module:115 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "" +"Geef een door komma's gescheiden lijst met argumenten op om naar de " +"view te sturen." + +#: nodereference.module:120 +msgid "<p>The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" +"<p>De lijst met nodes die kunnen worden gerefereerd, gebaseerd op een " +"\"Views module\"-view, maar geen passende views gevonden. <br />Merk " +"op:</p>" + +#: nodereference.module:205 +msgid "%name: invalid input." +msgstr "%name: geen toegestane waarde." + +#: nodereference.module:217 +msgid "%name: this post can't be referenced." +msgstr "%name: dit bericht kan niet worden gerefereerd." + +#: nodereference.module:242 +msgid "Title (link)" +msgstr "Titel (link)" + +#: nodereference.module:247 +msgid "Title (no link)" +msgstr "Titel (geen link)" + +#: nodereference.module:252 +msgid "Full node" +msgstr "Volledige node" + +#: nodereference.module:257 +msgid "Teaser" +msgstr "Voorbeeldweergave" + +#: nodereference.module:347 +msgid "Select list" +msgstr "Selectielijst" + +#: nodereference.module:355 +msgid "Check boxes/radio buttons" +msgstr "Vinkje/radio buttons" + +#: nodereference.module:363 +msgid "Autocomplete text field" +msgstr "Automatisch aanvullend tekstveld" + +#: nodereference.module:417 +msgid "Autocomplete matching" +msgstr "Automatisch aanvullende overeenkomst" + +#: nodereference.module:420 +msgid "Starts with" +msgstr "Begint met" + +#: nodereference.module:421 +msgid "Contains" +msgstr "Bevat" + +#: nodereference.module:423 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes." +msgstr "" +"Selecteer de methode die wordt gebruikt om automatisch aangevulde " +"suggesties te geven. Merk op <em>Bevat</em> prestatieproblemen kan " +"veroorzaken op sites met vele duizenden gebruikers." + +#: nodereference.module:671 +msgid "%name: title mismatch. Please check your selection." +msgstr "%name: titel niet gevonden. Controleer je selectie." + +#: nodereference.module:678 +msgid "%name: found no valid post with that title." +msgstr "%name: geen bericht gevonden met die titel." + +#: nodereference.module:15 +msgid "Nodereference autocomplete" +msgstr "Nodereferentie automatisch aanvullen" + +#: nodereference.module:0 +msgid "nodereference" +msgstr "nodereferentie" + +#: nodereference.info:0 +msgid "Node Reference" +msgstr "Nodereferentie" + +#: nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "Levert een veldtype for het refereren van een node naar een ander." + +#: nodereference.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.pot new file mode 100644 index 0000000000000000000000000000000000000000..cc8eeb9323074fc06bce4ebeab7948bd2fbdfc6c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.pot @@ -0,0 +1,114 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-nodereference) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# nodereference.module,v 1.138.2.55 2009/06/02 12:24:04 yched +# nodereference.info,v 1.8 2008/04/23 18:02:07 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/nodereference/nodereference.rules.inc:15 +msgid "Load a referenced node" +msgstr "" + +#: modules/nodereference/nodereference.rules.inc:19 +msgid "Content containing the node reference field" +msgstr "" + +#: modules/nodereference/nodereference.rules.inc:25 +msgid "Referenced content" +msgstr "" + +#: modules/nodereference/nodereference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first content node will be loaded." +msgstr "" + +#: modules/nodereference/nodereference.rules.inc:50 +msgid "There are no nodereference fields defined." +msgstr "" + +#: modules/nodereference/nodereference.module:69 +msgid "Node reference" +msgstr "" + +#: modules/nodereference/nodereference.module:70 +msgid "Store the ID of a related node as an integer value." +msgstr "" + +#: modules/nodereference/nodereference.module:85 +msgid "Content types that can be referenced" +msgstr "" + +#: modules/nodereference/nodereference.module:107 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "" + +#: modules/nodereference/nodereference.module:114 +msgid "View used to select the nodes" +msgstr "" + +#: modules/nodereference/nodereference.module:117 +msgid "<p>Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note:</p>" +msgstr "" + +#: modules/nodereference/nodereference.module:118;131 +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "" + +#: modules/nodereference/nodereference.module:130 +msgid "<p>The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +#: modules/nodereference/nodereference.module:228 +msgid "%name: this post can't be referenced." +msgstr "" + +#: modules/nodereference/nodereference.module:253 +msgid "Title (link)" +msgstr "" + +#: modules/nodereference/nodereference.module:258 +msgid "Title (no link)" +msgstr "" + +#: modules/nodereference/nodereference.module:435 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes." +msgstr "" + +#: modules/nodereference/nodereference.module:691 +msgid "%name: title mismatch. Please check your selection." +msgstr "" + +#: modules/nodereference/nodereference.module:698 +msgid "%name: found no valid post with that title." +msgstr "" + +#: modules/nodereference/nodereference.module:15 +msgid "Nodereference autocomplete" +msgstr "" + +#: modules/nodereference/nodereference.module:0 +msgid "nodereference" +msgstr "" + +#: modules/nodereference/nodereference.info:0 +msgid "Node Reference" +msgstr "" + +#: modules/nodereference/nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..53722637f6a6a672e210e72a45b3297dd2a6eb7c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.sv.po @@ -0,0 +1,179 @@ +# $Id$ +# +# Swedish translation of Drupal (nodereference) +# Generated from files: +# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# nodereference.module,v 1.138.2.54 2009/04/29 20:51:53 karens +# nodereference.info,v 1.8 2008/04/23 18:02:07 dww +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Nodereference 6.x\n" +"POT-Creation-Date: 2009-05-27 13:40+0200\n" +"PO-Revision-Date: 2009-05-27 14:40+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: nodereference.rules.inc:15 +msgid "Load a referenced node" +msgstr "Ladda en hänvisad nod" + +#: nodereference.rules.inc:19 +msgid "Content containing the node reference field" +msgstr "Innehåll som innehåller det hänvisade nodfältet" + +#: nodereference.rules.inc:25 +msgid "Referenced content" +msgstr "Hänvisat innehåll" + +#: nodereference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first content node will be loaded." +msgstr "Observera att om fält har flera värden, så kommer enbart den första innehållsnoden att laddas." + +#: nodereference.rules.inc:45 +msgid "Field" +msgstr "Fält" + +#: nodereference.rules.inc:50 +msgid "There are no nodereference fields defined." +msgstr "Det finns inga hänvisade nodfält definierade." + +#: nodereference.module:60 +msgid "Node reference" +msgstr "Hänvisad nod" + +#: nodereference.module:61 +msgid "Store the ID of a related node as an integer value." +msgstr "Lagra ID för en relaterad nod som ett heltalsvärde." + +#: nodereference.module:76 +msgid "Content types that can be referenced" +msgstr "Innehållstyper som kan hänvisas" + +#: nodereference.module:88 +msgid "Default Views" +msgstr "Förvald vy" + +#: nodereference.module:91 +msgid "Existing Views" +msgstr "Existerande vyer" + +#: nodereference.module:98 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Avancerat - Noder som kan hänvisas (Vyer)" + +#: nodereference.module:105 +msgid "View used to select the nodes" +msgstr "Vy som används för att välja noder" + +#: nodereference.module:108 +msgid "<p>Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note:</p>" +msgstr "<p>Välj \"modulen Views\" vy som väljer noden som kan hänvisas.<br />Observera:</p>" + +#: nodereference.module:109;122 +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "<ul><li>Enbart vyer som har fält kommer att fungera för detta ändamål.</li><li>Detta kommer att bryta mot inställningarna för \"Innehållstyper\" ovan. Använd vyns \"filtrering\" istället.</li><li>Använd vyns \"fält\" för att visa ytterligare information om kandiderande noder på formuläret för att skapa/redigera nod</li><li>Använd vyns \"sorteringskriterier\" för att bestämma ordningen på vilken de kandiderande noder kommer att visas</li></ul>" + +#: nodereference.module:113 +msgid "View arguments" +msgstr "Argument för vy" + +#: nodereference.module:116 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Tillhandahåll en kommaseparerad lista av argument att skicka till vyn." + +#: nodereference.module:121 +msgid "<p>The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "<p>Listan av noder som kan hänvisas kan baseras på en vy från \"modulen Views\", men inga lämpliga vyer hittades. <br />Observera</p>" + +#: nodereference.module:207 +msgid "%name: invalid input." +msgstr "%name: ogiltig inmatning." + +#: nodereference.module:219 +msgid "%name: this post can't be referenced." +msgstr "%name: denna post kan inte hänvisas." + +#: nodereference.module:244 +msgid "Title (link)" +msgstr "Titel (länk)" + +#: nodereference.module:249 +msgid "Title (no link)" +msgstr "Titel (ingen länk)" + +#: nodereference.module:254 +msgid "Full node" +msgstr "Fullständig nod" + +#: nodereference.module:259 +msgid "Teaser" +msgstr "Förhandstitt" + +#: nodereference.module:349 +msgid "Select list" +msgstr "Listval" + +#: nodereference.module:357 +msgid "Check boxes/radio buttons" +msgstr "Kryssrutor/radioknappar" + +#: nodereference.module:365 +msgid "Autocomplete text field" +msgstr "Automatiskt kompletterande textfält" + +#: nodereference.module:420 +msgid "Autocomplete matching" +msgstr "Automatiskt kompletterande som överensstämmer" + +#: nodereference.module:423 +msgid "Starts with" +msgstr "Börjar med" + +#: nodereference.module:424 +msgid "Contains" +msgstr "Innehåller" + +#: nodereference.module:426 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes." +msgstr "Välj metod att använda för att samla in automatiskt kompletterande förslag. Observera att <em>Innehåller</em> kan orsaka prestandaproblem med webbplatser som har tusentals noder." + +#: nodereference.module:430 +msgid "Size of textfield" +msgstr "Storlek på textfält" + +#: nodereference.module:682 +msgid "%name: title mismatch. Please check your selection." +msgstr "%name: titel stämmer inte. Var vänlig kontrollera ditt urval." + +#: nodereference.module:689 +msgid "%name: found no valid post with that title." +msgstr "%name: hittade ingen giltig post med denna titel." + +#: nodereference.module:15 +msgid "Nodereference autocomplete" +msgstr "Automatiskt kompletterande nodhänvisning" + +#: nodereference.module:0 +msgid "nodereference" +msgstr "nodereference" + +#: nodereference.info:0 +msgid "Node Reference" +msgstr "Hänvisning av nod" + +#: nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "Definierar en fälttyp för att hänvisa en nod till en annan." + +#: nodereference.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..205c2259cc1c147f277a945a356225a9d9594315 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.help.ini @@ -0,0 +1,8 @@ +; $Id$ + +[advanced help settings] +hide = TRUE + +[number] +title = Number field +parent = content%fields diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.html new file mode 100644 index 0000000000000000000000000000000000000000..8725d75b442b3052d5ffc1856cdb60e17988c484 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.html @@ -0,0 +1,2 @@ +<p>The Number field stores numeric data in the database. It can either be an integer value, a decimal value, or a float value.</p> +<p>The Number field provides a place for the administrator to create a list of 'Allowed values' for the field. When used with <a href="&topic:optionwidgets/optionwidgets&">Optionwidgets</a>, the allowed values are presented to the end user in a drop-down select list, checkboxes, or radios.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.info new file mode 100644 index 0000000000000000000000000000000000000000..4b00d32cb6ec675a7318cb01b72d4952ec8c0852 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.info @@ -0,0 +1,12 @@ +; $Id$ +name = Number +description = Defines numeric field types. +dependencies[] = content +package = CCK +core = 6.x +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.install new file mode 100644 index 0000000000000000000000000000000000000000..f9e794ec26b53e3b6cd5ea91265fb4e82e4544dc --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.install @@ -0,0 +1,60 @@ +<?php +// $Id$ + +/** + * @file + * Implementation of hook_install(). + */ +function number_install() { + drupal_load('module', 'content'); + content_notify('install', 'number'); +} + +/** + * Implementation of hook_uninstall(). + */ +function number_uninstall() { + drupal_load('module', 'content'); + content_notify('uninstall', 'number'); +} + +/** + * Implementation of hook_enable(). + * + * Notify content module when this module is enabled. + */ +function number_enable() { + drupal_load('module', 'content'); + content_notify('enable', 'number'); +} + +/** + * Implementation of hook_disable(). + * + * Notify content module when this module is disabled. + */ +function number_disable() { + drupal_load('module', 'content'); + content_notify('disable', 'number'); +} + +function number_update_last_removed() { + return 5; +} + +/** + * Rename old decimal fields, which were really floats, to float + */ +function number_update_6000() { + if ($abort = content_check_update('number')) { + return $abort; + } + + $ret = array(); + + drupal_load('module', 'content'); + $ret[] = update_sql("UPDATE {". content_field_tablename() ."} SET type='number_float' WHERE type = 'number_decimal'"); + + content_clear_type_cache(); + return $ret; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.module new file mode 100644 index 0000000000000000000000000000000000000000..108e58936f1f014ad09a0e5b5f2bf53cba4b3f25 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.module @@ -0,0 +1,585 @@ +<?php +// $Id$ + +/** + * @file + * Defines numeric field types. + */ + +/** + * Implementation of hook_theme(). + */ +function number_theme() { + return array( + 'number' => array('arguments' => array('element' => NULL)), + 'number_formatter_default' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_us_0' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_us_1' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_us_2' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_be_0' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_be_1' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_be_2' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_fr_0' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_fr_1' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_fr_2' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'), + 'number_formatter_unformatted' => array('arguments' => array('element' => NULL)), + ); +} + +/** + * Implementation of hook_field_info(). + */ +function number_field_info() { + return array( + 'number_integer' => array( + 'label' => t('Integer'), + 'description' => t('Store a number in the database as an integer.'), +// 'content_icon' => 'icon_content_number.png', + ), + 'number_decimal' => array( + 'label' => t('Decimal'), + 'description' => t('Store a number in the database in a fixed decimal format.'), +// 'content_icon' => 'icon_content_number.png', + ), + 'number_float' => array( + 'label' => t('Float'), + 'description' => t('Store a number in the database in a floating point format.'), +// 'content_icon' => 'icon_content_number.png', + ), + ); +} + +/** + * Implementation of hook_field_settings(). + */ +function number_field_settings($op, $field) { + switch ($op) { + case 'form': + $form = array(); + $form['min'] = array( + '#type' => 'textfield', + '#title' => t('Minimum'), + '#element_validate' => array('_element_validate_number'), + '#default_value' => is_numeric($field['min']) ? $field['min'] : '', + ); + $form['max'] = array( + '#type' => 'textfield', + '#title' => t('Maximum'), + '#element_validate' => array('_element_validate_number'), + '#default_value' => is_numeric($field['max']) ? $field['max'] : '', + ); + if ($field['type'] == 'number_decimal') { + $form['precision'] = array( + '#type' => 'select', + '#options' => drupal_map_assoc(range(10, 32)), + '#title' => t('Precision'), + '#description' => t('The total number of digits to store in the database, including those to the right of the decimal.'), + '#default_value' => is_numeric($field['precision']) ? $field['precision'] : 10, + ); + $form['scale'] = array( + '#type' => 'select', + '#options' => drupal_map_assoc(range(0, 10)), + '#title' => t('Scale'), + '#description' => t('The number of digits to the right of the decimal.'), + '#default_value' => is_numeric($field['scale']) ? $field['scale'] : 2, + ); + $form['decimal'] = array( + '#type' => 'select', + '#options' => array('.' => 'decimal point', ',' => 'comma', ' ' => 'space'), + '#title' => t('Decimal marker'), + '#description' => t('The character users will input to mark the decimal point in forms.'), + '#default_value' => !empty($field['decimal']) ? $field['decimal'] : '.', + ); + } + $form['append']['prefix'] = array( + '#type' => 'textfield', + '#title' => t('Prefix'), + '#size' => 60, + '#default_value' => !empty($field['prefix']) ? $field['prefix'] : '', + '#description' => t('Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds).'), + ); + $form['append']['suffix'] = array( + '#type' => 'textfield', + '#title' => t('Suffix'), + '#size' => 60, + '#default_value' => !empty($field['suffix']) ? $field['suffix'] : '', + '#description' => t('Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds).'), + ); + $form['allowed_values_fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Allowed values'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['allowed_values_fieldset']['allowed_values'] = array( + '#type' => 'textarea', + '#title' => t('Allowed values list'), + '#default_value' => !empty($field['allowed_values']) ? $field['allowed_values'] : '', + '#required' => FALSE, + '#rows' => 10, + '#description' => t('The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags', array('%type' => $field['type'], '@tags' => _content_filter_xss_display_allowed_tags())), + ); + $form['allowed_values_fieldset']['advanced_options'] = array( + '#type' => 'fieldset', + '#title' => t('PHP code'), + '#collapsible' => TRUE, + '#collapsed' => empty($field['allowed_values_php']), + ); + if (user_access('Use PHP input for field settings (dangerous - grant with care)')) { + $form['allowed_values_fieldset']['advanced_options']['allowed_values_php'] = array( + '#type' => 'textarea', + '#title' => t('Code'), + '#default_value' => !empty($field['allowed_values_php']) ? $field['allowed_values_php'] : '', + '#rows' => 6, + '#description' => t('Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above.'), + ); + } + else { + $form['allowed_values_fieldset']['advanced_options']['markup_allowed_values_php'] = array( + '#type' => 'item', + '#title' => t('Code'), + '#value' => !empty($field['allowed_values_php']) ? '<code>'. check_plain($field['allowed_values_php']) .'</code>' : t('<none>'), + '#description' => empty($field['allowed_values_php']) ? t("You're not allowed to input PHP code.") : t('This PHP code was set by an administrator and will override the allowed values list above.'), + ); + } + return $form; + + case 'save': + $values = array('prefix', 'suffix', 'min', 'max', 'allowed_values', 'allowed_values_php'); + if ($field['type'] == 'number_decimal') { + $values = array_merge($values, array('precision', 'scale', 'decimal')); + } + return $values; + + case 'database columns': + if ($field['type'] == 'number_integer') { + return array( + 'value' => array('type' => 'int', 'not null' => FALSE, 'sortable' => TRUE), + ); + } + if ($field['type'] == 'number_float') { + return array( + 'value' => array('type' => 'float', 'not null' => FALSE, 'sortable' => TRUE), + ); + } + if ($field['type'] == 'number_decimal') { + $precision = isset($field['precision']) ? $field['precision'] : 10; + $scale = isset($field['scale']) ? $field['scale'] : 2; + return array( + 'value' => array('type' => 'numeric', 'precision' => $precision, 'scale' => $scale, 'not null' => FALSE, 'sortable' => TRUE), + ); + } + + case 'views data': + $allowed_values = content_allowed_values($field); + if (count($allowed_values)) { + $data = content_views_field_views_data($field); + $db_info = content_database_info($field); + $table_alias = content_views_tablename($field); + + // Filter: Add a 'many to one' filter. + $copy = $data[$table_alias][$field['field_name'] .'_value']; + $copy['title'] = t('@label (!name) - Allowed values', array('@label' => t($field['widget']['label']), '!name' => $field['field_name'])); + $copy['filter']['handler'] = 'content_handler_filter_many_to_one'; + $copy['filter']['numeric'] = TRUE; + unset($copy['field'], $copy['argument'], $copy['sort']); + $data[$table_alias][$field['field_name'] .'_value_many_to_one'] = $copy; + // Argument: swap the handler to the 'many to one' operator + $data[$table_alias][$field['field_name'] .'_value']['argument']['handler'] = 'content_handler_argument_many_to_one'; + $data[$table_alias][$field['field_name'] .'_value']['argument']['numeric'] = TRUE; + return $data; + } + break; + } +} + +function _number_widget_settings_min_validate($element, &$form_state) { + $value = $form_state['values']['min']; + if ($value && !is_numeric($value)) { + form_set_error('min', t('"Minimum" must be a number.')); + } +} + +function _number_widget_settings_max_validate($element, &$form_state) { + $value = $form_state['values']['max']; + if ($value && !is_numeric($value)) { + form_set_error('max', t('"Maximum" must be a number.')); + } +} + +/** + * Implementation of hook_field(). + */ +function number_field($op, &$node, $field, &$items, $teaser, $page) { + switch ($op) { + case 'validate': + $allowed_values = content_allowed_values($field); + if (is_array($items)) { + foreach ($items as $delta => $item) { + $error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; + if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); + if ($item['value'] != '') { + if (is_numeric($field['min']) && $item['value'] < $field['min']) { + form_set_error($error_element, t('%name: the value may be no smaller than %min.', array('%name' => t($field['widget']['label']), '%min' => $field['min']))); + } + if (is_numeric($field['max']) && $item['value'] > $field['max']) { + form_set_error($error_element, t('%name: the value may be no larger than %max.', array('%name' => t($field['widget']['label']), '%max' => $field['max']))); + } + if (count($allowed_values)) { + // We cannot use array_key_exists() because allowed values are + // stored as strings, and we need to compare numeric equality. + $valid = FALSE; + foreach ($allowed_values as $kay => $value) { + if ((float) $item['value'] == (float) $kay) { + $valid = TRUE; + break; + } + } + if (!$valid) { + form_set_error($error_element, t('%name: illegal value.', array('%name' => t($field['widget']['label'])))); + } + } + } + } + } + return $items; + } +} + +/** + * Implementation of hook_content_is_empty(). + */ +function number_content_is_empty($item, $field) { + if (empty($item['value']) && (string)$item['value'] !== '0') { + return TRUE; + } + return FALSE; +} + +/** + * Implementation of hook_field_formatter_info(). + */ +function number_field_formatter_info() { + return array( + 'default' => array('label' => '9999', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')), + 'us_0' => array('label' => '9,999', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')), + 'us_1' => array('label' => '9,999.9', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')), + 'us_2' => array('label' => '9,999.99', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')), + 'be_0' => array('label' => '9.999', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')), + 'be_1' => array('label' => '9.999,9', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')), + 'be_2' => array('label' => '9.999,99', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')), + 'fr_0' => array('label' => '9 999', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')), + 'fr_1' => array('label' => '9 999, 9', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')), + 'fr_2' => array('label' => '9 999, 99', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')), + 'unformatted' => array('label' => t('unformatted'), 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')), + ); +} + +/** + * Proxy theme function for 'unformatted' number field formatter. + */ +function theme_number_formatter_unformatted($element) { + return $element['#item']['value']; +} + +/** + * Proxy theme function for number field formatters. + */ +function theme_number_formatter_generic($element) { + $field = content_fields($element['#field_name'], $element['#type_name']); + $value = $element['#item']['value']; + + if (($allowed_values = content_allowed_values($field))) { + if (isset($allowed_values[$value]) && $allowed_values[$value] != $value) { + return $allowed_values[$value]; + } + } + + if (empty($value) && $value !== '0') { + return ''; + } + + switch ($element['#formatter']) { + case 'us_0': + $output = number_format($value, 0, '.', ','); + break; + case 'us_1': + $output = number_format($value, 1, '.', ','); + break; + case 'us_2': + $output = number_format($value, 2, '.', ','); + break; + case 'be_0': + $output = number_format($value, 0, ',', '.'); + break; + case 'be_1': + $output = number_format($value, 1, ',', '.'); + break; + case 'be_2': + $output = number_format($value, 2, ',', '.'); + break; + case 'fr_0': + $output = number_format($value, 0, ', ', ' '); + break; + case 'fr_1': + $output = number_format($value, 1, ', ', ' '); + break; + case 'fr_2': + $output = number_format($value, 2, ', ', ' '); + break; + default: + $output = $value; + break; + } + + $prefixes = isset($field['prefix']) ? array_map('content_filter_xss', explode('|', $field['prefix'])) : array(''); + $suffixes = isset($field['suffix']) ? array_map('content_filter_xss', explode('|', $field['suffix'])) : array(''); + $prefix = (count($prefixes) > 1) ? format_plural($value, $prefixes[0], $prefixes[1]) : $prefixes[0]; + $suffix = (count($suffixes) > 1) ? format_plural($value, $suffixes[0], $suffixes[1]) : $suffixes[0]; + + return $prefix . $output . $suffix; +} + +/** + * Implementation of hook_widget_info(). + * + * Here we indicate that the content module will handle + * the default value and multiple values for these widgets. + * + * Callbacks can be omitted if default handing is used. + * They're included here just so this module can be used + * as an example for custom modules that might do things + * differently. + */ +function number_widget_info() { + return array( + 'number' => array( + 'label' => t('Text field'), + 'field types' => array('number_integer', 'number_decimal', 'number_float'), + 'multiple values' => CONTENT_HANDLE_CORE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + ); +} + +/** + * Implementation of FAPI hook_elements(). + * + * Any FAPI callbacks needed for individual widgets can be declared here, + * and the element will be passed to those callbacks for processing. + * + * Drupal will automatically theme the element using a theme with + * the same name as the hook_elements key. + * + * Includes a regex to check for valid values as an additional parameter + * the validator can use. The regex can be overridden if necessary. + */ +function number_elements() { + return array( + 'number' => array( + '#input' => TRUE, + '#columns' => array('value'), '#delta' => 0, + '#process' => array('number_process'), + ), + ); +} + +/** + * Implementation of hook_widget(). + * + * Attach a single form element to the form. It will be built out and + * validated in the callback(s) listed in hook_elements. We build it + * out in the callbacks rather than here in hook_widget so it can be + * plugged into any module that can provide it with valid + * $field information. + * + * Content module will set the weight, field name and delta values + * for each form element. This is a change from earlier CCK versions + * where the widget managed its own multiple values. + * + * If there are multiple values for this field, the content module will + * call this function as many times as needed. + * + * @param $form + * the entire form array, $form['#node'] holds node information + * @param $form_state + * the form_state, $form_state['values'][$field['field_name']] + * holds the field's form values. + * @param $field + * the field array + * @param $items + * array of default values for this field + * @param $delta + * the order of this item in the array of subelements (0, 1, 2, etc) + * + * @return + * the form item for a single element for this field + */ +function number_widget(&$form, &$form_state, $field, $items, $delta = 0) { + $element = array( + '#type' => $field['widget']['type'], + '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL, + ); + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function number_process($element, $edit, $form_state, $form) { + $field_name = $element['#field_name']; + $field = $form['#field_info'][$field_name]; + $field_key = $element['#columns'][0]; + + $value = isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : ''; + $value = isset($field['decimal']) ? str_replace('.', $field['decimal'], $value) : $value; + $element[$field_key] = array( + '#type' => 'textfield', + '#default_value' => $value, + // Need to allow a slightly larger size that the field length to allow + // for some configurations where all characters won't fit in input field. + '#size' => isset($field['precision']) ? $field['precision'] + 2 : 12, + '#maxlength' => isset($field['precision']) ? $field['precision'] : 10, + '#attributes' => array('class' => 'number'), + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#description' => $element['#description'], + '#required' => $element['#required'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + + $prefixes = array(); + $suffixes = array(); + + // Make sure we don't wipe out element validation added elsewhere. + if (empty($element['#element_validate'])) { + $element['#element_validate'] = array(); + } + if (!empty($field['prefix'])) { + $prefixes = explode('|', $field['prefix']); + $element[$field_key]['#field_prefix'] = content_filter_xss(array_pop($prefixes)); + } + if (!empty($field['suffix'])) { + $suffixes = explode('|', $field['suffix']); + $element[$field_key]['#field_suffix'] = content_filter_xss(array_pop($suffixes)); + } + switch ($field['type']) { + case 'number_float': + $element['#element_validate'][] = 'number_float_validate'; + break; + case 'number_integer': + $element['#element_validate'][] = 'number_integer_validate'; + break; + case 'number_decimal': + $element['#element_validate'][] = 'number_decimal_validate'; + $element['#decimal'] = isset($field['decimal']) ? $field['decimal'] : '.'; + $element['#precision'] = isset($field['precision']) ? $field['precision'] : 10; + $element['#scale'] = isset($field['scale']) ? $field['scale'] : 2; + break; + } + + // Used so that hook_field('validate') knows where to flag an error. + $element['_error_element'] = array( + '#type' => 'value', + '#value' => implode('][', array_merge($element['#parents'], array($field_key))), + ); + + return $element; +} + +/** + * FAPI validation of an individual float element. + */ +function number_float_validate($element, &$form_state) { + $field_name = $element['#field_name']; + $type_name = $element['#type_name']; + $field = content_fields($field_name, $type_name); + $field_key = $element['#columns'][0]; + $value = $element['#value'][$field_key]; + + if (($element[$field_key]['#required'] || !empty($value))) { + $start = $value; + $value = preg_replace('@[^-0-9\.]@', '', $value); + if ($start != $value) { + $error_field = implode('][', $element['#parents']) .']['. $field_key; + form_set_error($error_field, t('Only numbers and decimals are allowed in %field.', array('%field' => t($field['widget']['label'])))); + } + else { + form_set_value($element[$field_key], $value, $form_state); + } + } +} + +/** + * FAPI validation of an individual integer element. + */ +function number_integer_validate($element, &$form_state) { + $field_name = $element['#field_name']; + $type_name = $element['#type_name']; + $field = content_fields($field_name, $type_name); + $field_key = $element['#columns'][0]; + $value = $element['#value'][$field_key]; + + if (($element[$field_key]['#required'] || !empty($value))) { + $start = $value; + $value = preg_replace('@[^-0-9]@', '', $value); + if ($start != $value) { + $error_field = implode('][', $element['#parents']) .']['. $field_key; + form_set_error($error_field, t('Only numbers are allowed in %field.', array('%field' => t($field['widget']['label'])))); + } + else { + form_set_value($element[$field_key], $value, $form_state); + } + } +} + +/** + * FAPI validation of an individual decimal element. + */ +function number_decimal_validate($element, &$form_state) { + $field_name = $element['#field_name']; + $type_name = $element['#type_name']; + $field = content_fields($field_name, $type_name); + $field_key = $element['#columns'][0]; + $value = $element['#value'][$field_key]; + + if (($element[$field_key]['#required'] || !empty($value))) { + $decimal = $element['#decimal'] ? $element['#decimal'] : '.'; + $start = $value; + $value = preg_replace('@[^-0-9\\'. $decimal .']@', '', $value); + if ($start != $value) { + $error_field = implode('][', $element['#parents']) .']['. $field_key; + form_set_error($error_field, t('Only numbers and the decimal character (%decimal) are allowed in %field.', array('%decimal' => $element['#decimal'], '%field' => t($field['widget']['label'])))); + } + else { + $value = str_replace($element['#decimal'], '.', $value); + $value = round($value, $element['#scale']); + form_set_value($element[$field_key], $value, $form_state); + } + } +} + +/** + * FAPI theme for an individual number element. + * + * The textfield is already rendered by the textfield + * theme and the HTML output lives in $element['#children']. + * Override this theme to make custom changes to the output. + * + * $element['#field_name'] contains the field name + * $element['#delta] is the position of this element in the group + */ +function theme_number($element) { + return $element['#children']; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.de.po new file mode 100644 index 0000000000000000000000000000000000000000..b9ed3f525c01d3b1ea84239a7392059b4ea6c7e2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.de.po @@ -0,0 +1,152 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2008-11-05 12:54+0100\n" +"PO-Revision-Date: 2008-11-05 13:18+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/number/number.module:34 +msgid "Integer" +msgstr "Ganzzahl" + +#: modules/number/number.module:35 +msgid "Store a number in the database as an integer." +msgstr "Speichert die Zahl in der Datenbank als Ganzzahl." + +#: modules/number/number.module:38 +msgid "Decimal" +msgstr "Dezimalzahl" + +#: modules/number/number.module:39 +msgid "Store a number in the database in a fixed decimal format." +msgstr "Speichert die Zahl in der Datenbank in einem festen Dezimalformat." + +#: modules/number/number.module:42 +msgid "Float" +msgstr "Fließkommazahl" + +#: modules/number/number.module:43 +msgid "Store a number in the database in a floating point format." +msgstr "Speichert die Zahl in der Datenbank in einem Fließkommaformat." + +#: modules/number/number.module:57 +msgid "Minimum" +msgstr "Minimum" + +#: modules/number/number.module:63 +msgid "Maximum" +msgstr "Maximum" + +#: modules/number/number.module:71 +msgid "Precision" +msgstr "Präzision" + +#: modules/number/number.module:72 +msgid "The total number of digits to store in the database, including those to the right of the decimal." +msgstr "Die gesamte Anzahl der in der Datenbank zu speichernden Stellen, inclusive der rechts vom Dezimaltrennzeichen angegebenen." + +#: modules/number/number.module:78 +msgid "Scale" +msgstr "Skalierung" + +#: modules/number/number.module:79 +msgid "The number of digits to the right of the decimal." +msgstr "Die Anzahl der rechts vom Dezimaltrennzeichen angegebenen Stellen." + +#: modules/number/number.module:85 +msgid "Decimal marker" +msgstr "Dezimalzeichen" + +#: modules/number/number.module:86 +msgid "The character users will input to mark the decimal point in forms." +msgstr "Das von Benutzern in Formularen als Dezimalzeichen zu verwendende Symbol." + +#: modules/number/number.module:92 +msgid "Prefix" +msgstr "Präfix" + +#: modules/number/number.module:95 +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Eine Zeichenkette angeben, welche dem Wert vorrangestellt werden soll, z.b. $ oder €. Ansonsten freilassen. Werte für Einzahl und Mehrzahl mit einer Pipe trennen (Pfund|Pfunde)." + +#: modules/number/number.module:99 +msgid "Suffix" +msgstr "Suffix" + +#: modules/number/number.module:102 +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Eine Zeichenkette angeben, welche dem Wert angehängt werden soll, z.b. m², m/s², kb/s. Ansonsten freilassen. Werte für Einzahl und Mehrzahl mit einer Pipe trennen (Pfund|Pfunde)." + +#: modules/number/number.module:195 +msgid "\"Minimum\" must be a number." +msgstr "„Minimum“ muss eine Zahl sein." + +#: modules/number/number.module:202 +msgid "\"Maximum\" must be a number." +msgstr "„Maximum“ muss eine Zahl sein." + +#: modules/number/number.module:219 +msgid "%name: the value may be no smaller than %min." +msgstr "%name: Der Wert darf nicht kleiner als %min sein." + +#: modules/number/number.module:222 +msgid "%name: the value may be no larger than %max." +msgstr "%name: Der Wert darf nicht grösser als %max sein." + +#: modules/number/number.module:270 +msgid "unformatted" +msgstr "unformatiert" + +# Float validation: English needs work +#: modules/number/number.module:509 +#, fuzzy +msgid "Only numbers and decimals are allowed in %field." +msgstr "Im Feld %field sind nur Ganzzahlen und Fließkommazahlen zulässig." + +# Integer validation: English needs work +#: modules/number/number.module:532 +#, fuzzy +msgid "Only numbers are allowed in %field." +msgstr "Im Feld %field sind nur Ganzzahlen zulässig." + +# Decimal validation with decimal character: English needs work +#: modules/number/number.module:556 +#, fuzzy +msgid "Only numbers and the decimal character (%decimal) are allowed in %field." +msgstr "Im Feld %field sind nur Dezimalzahlen und das Dezimaltrennzeichen (%decimal) zulässig." + +#: modules/number/number.module:0 +msgid "number" +msgstr "Zahl" + +#: modules/number/number.info:0 +msgid "Number" +msgstr "Zahl" + +#: modules/number/number.info:0 +msgid "Defines numeric field types." +msgstr "Definiert einen numerischen Feldtyp." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..b1b913f5474b8d0c2596eb40aff1464b2a749668 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.fr.po @@ -0,0 +1,163 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 13:24+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: modules/number/number.module:41 +msgid "Integer" +msgstr "Entier" + +#: modules/number/number.module:42 +msgid "Store a number in the database as an integer." +msgstr "Enregistre un nombre dans la base de données en tant qu'entier." + +#: modules/number/number.module:49 +msgid "Decimal" +msgstr "Décimal" + +#: modules/number/number.module:50 +msgid "Store a number in the database in a fixed decimal format." +msgstr "Enregistre un nombre dans la base de données en format décimal fixe." + +#: modules/number/number.module:57 +msgid "Float" +msgstr "Réel à virgule flottante" + +#: modules/number/number.module:58 +msgid "Store a number in the database in a floating point format." +msgstr "" +"Enregistre un nombre dans la base de données en format réel à virgule " +"flottante." + +#: modules/number/number.module:76 +msgid "Minimum" +msgstr "Minimum" + +#: modules/number/number.module:81 +msgid "Maximum" +msgstr "Maximum" + +#: modules/number/number.module:88 +msgid "Precision" +msgstr "Précision" + +#: modules/number/number.module:89 +msgid "" +"The total number of digits to store in the database, including those to the " +"right of the decimal." +msgstr "" +"Nombre total de chiffres à enregistrer dans la base de données, y compris " +"ceux à droite du marqueur décimal." + +#: modules/number/number.module:95 +msgid "Scale" +msgstr "Échelle" + +#: modules/number/number.module:96 +msgid "The number of digits to the right of the decimal." +msgstr "Nombre de chiffres à la droite du marqueur décimal." + +#: modules/number/number.module:102 +msgid "Decimal marker" +msgstr "Marqueur décimal" + +#: modules/number/number.module:103 +msgid "The character users will input to mark the decimal point in forms." +msgstr "" +"Caractère employé par les utilisateurs dans les formulaires pour signaler la " +"partie décimale des nombres." + +#: modules/number/number.module:109 +msgid "Prefix" +msgstr "Préfixe" + +#: modules/number/number.module:112 +msgid "" +"Define a string that should be prefixed to the value, like $ or €. Leave " +"blank for none. Separate singular and plural values with a pipe (pound|" +"pounds)." +msgstr "" +"Définissez une chaîne de caractères à utiliser pour préfixer la valeur, par " +"exemple $ ou €. Laissez vide pour ne rien afficher de plus. Séparez les " +"valeurs singulier et pluriel par une barre verticale (euro|euros)." + +#: modules/number/number.module:116 +msgid "Suffix" +msgstr "Suffixe" + +#: modules/number/number.module:119 +msgid "" +"Define a string that should suffixed to the value, like m², m/s², kb/s. " +"Leave blank for none. Separate singular and plural values with a pipe (pound|" +"pounds)." +msgstr "" +"Définissez une chaîne de caractères à utiliser pour suffixerla valeur, par " +"exemple m², m/s², ko/s. Laissez vide pour ne rien afficher de plus. Séparez " +"les valeurs singulier et pluriel par une barre verticale (euro|euros)." + +#: modules/number/number.module:162 +msgid "\"Minimum\" must be a number." +msgstr "'Minimum' doit être un nombre." + +#: modules/number/number.module:165 +msgid "\"Maximum\" must be a number." +msgstr "'Maximum' doit être un nombre." + +#: modules/number/number.module:222 +msgid "The value of %name may be no smaller than %min." +msgstr "La valeur de '%name 'ne peut être plus petite que %min." + +#: modules/number/number.module:225 +msgid "The value of %name may be no larger than %max." +msgstr "La valeur de '%name' ne peut pas être plus grande que %max." + +#: modules/number/number.module:263 +msgid "unformatted" +msgstr "non mis en forme" + +#: modules/number/number.module:476 +msgid "" +"Only numbers and decimals are allowed in %field. %start was changed to %" +"value." +msgstr "" +"Seuls des nombres et des décimaux sont autorisés dans '%field'. La valeur " +"saisie, '%start', a été modifié en '%value'." + +#: modules/number/number.module:494 +msgid "Only numbers are allowed in %field. %start was changed to %value." +msgstr "" +"Seuls des nombres sont autorisés dans '%field'. La valeur saisie, '%start', " +"a été modifié en '%value'." + +#: modules/number/number.module:513 +msgid "" +"Only numbers and the decimal character (%decimal) are allowed in %field. %" +"start was changed to %value." +msgstr "" +"Seuls des nombres et le marqueur décimal (%decimal) sont autorisés dans '%" +"field'. La valeur saisie, '%start', a été modifié en '%value'." + +#: modules/number/number.module:0 +msgid "number" +msgstr "number" + +#: modules/number/number.info:0 +msgid "Number" +msgstr "Number" + +#: modules/number/number.info:0 +msgid "Defines numeric field types." +msgstr "Permet de définir des champs numériques" diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..8e8183873137962005c112b6b001967bf9cb53b1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.hu.po @@ -0,0 +1,228 @@ +# Hungarian translation of number (all releases) +# Copyright (c) 2008 by the Hungarian translation team +# Generated from files: +# number.module,v 1.91.2.23 2008/10/06 15:11:39 karens +# number.info,v 1.7 2008/04/23 18:02:16 dww +# +msgid "" +msgstr "" +"Project-Id-Version: number (all releases)\n" +"POT-Creation-Date: 2008-10-26 11:25-0500\n" +"PO-Revision-Date: 2008-10-26 09:39-0500\n" +"Last-Translator: Fehér János <feher.janos _at- mindworks.hu>\n" +"Language-Team: Drupal.hu Fordítói Csapat <forditas [at] drupal.hu>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: number.module:147,156 +msgid "Code" +msgstr "Kód" + +#: number.info:0 +msgid "Number" +msgstr "Szám" + +#: number.module:91 +msgid "Precision" +msgstr "Helyiértékek" + +#: number.module:112 +msgid "Prefix" +msgstr "Előtag" + +#: number.module:119 +msgid "Suffix" +msgstr "Toldalék" + +#: number.info:0 +msgid "CCK" +msgstr "CCK" + +#: number.module:140 +msgid "PHP code" +msgstr "PHP kód" + +#: number.module:157 +msgid "<none>" +msgstr "<nincs>" + +#: number.module:158 +msgid "You're not allowed to input PHP code." +msgstr "Nem engedélyezett a PHP kód bevitele." + +#: number.module:42 +msgid "Integer" +msgstr "Egész szám" + +#: number.module:43 +msgid "Store a number in the database as an integer." +msgstr "Egészként tárol számot az adatbázisban." + +#: number.module:50 +msgid "Decimal" +msgstr "Decimális" + +#: number.module:51 +msgid "Store a number in the database in a fixed decimal format." +msgstr "Rögzített tízes számot tárol az adatbázisban" + +#: number.module:58 +msgid "Float" +msgstr "Lebegőpontos" + +#: number.module:59 +msgid "Store a number in the database in a floating point format." +msgstr "Lebegőpontos számot tárol az adatbázisban." + +#: number.module:77 +msgid "Minimum" +msgstr "Minimum" + +#: number.module:83 +msgid "Maximum" +msgstr "Maximum" + +#: number.module:92 +msgid "" +"The total number of digits to store in the database, including those " +"to the right of the decimal." +msgstr "" +"Az adatbázisban tárolt számjegyek teljes száma, beleértve a " +"tizedesponttól jobbra lévő számjegyeket is." + +#: number.module:98 +msgid "Scale" +msgstr "Felbontás" + +#: number.module:99 +msgid "The number of digits to the right of the decimal." +msgstr "A számjegyek száma." + +#: number.module:105 +msgid "Decimal marker" +msgstr "Decimális jelölő" + +#: number.module:106 +msgid "The character users will input to mark the decimal point in forms." +msgstr "Az űrlapokon a tizedespont jelölésére használt karakter." + +#: number.module:115 +msgid "" +"Define a string that should be prefixed to the value, like $ or €. " +"Leave blank for none. Separate singular and plural values with a pipe " +"(pound|pounds)." +msgstr "" +"Egy karaktersorozat, ami az érték előtagja lehet, mint például a " +"$ vagy az €. Ha nincs előtag, akkor üresen kell hagyni. " +"Függőleges vonallal lehet elválasztani egymástól az egyes és a " +"többes számú alakot (font|fontok)." + +#: number.module:122 +msgid "" +"Define a string that should suffixed to the value, like m², m/s², " +"kb/s. Leave blank for none. Separate singular and plural values with a " +"pipe (pound|pounds)." +msgstr "" +"Egy karaktersorozat, ami az érték toldaléka lehet, mint például " +"m², m/s², kb/s. Ha nincs toldalék, akkor üresen kell hagyni. " +"Függőleges vonallal lehet elválasztani egymástól az egyes és a " +"többes számú alakot (font|fontok)." + +#: number.module:126 +msgid "Allowed values" +msgstr "Megengedett értékek" + +#: number.module:132 +msgid "Allowed values list" +msgstr "Megengedett értékek" + +#: number.module:136 +msgid "" +"The possible values this field can contain. Enter one value per line, " +"in the format key|label. The key is the value that will be stored in " +"the database, and it must match the field storage type (%type). The " +"label is optional, and the key will be used as the label if no label " +"is specified.<br />Allowed HTML tags: @tags" +msgstr "" +"A mező lehetséges értékei. Egy sorban egy értéket lehet megadni " +"kulcs|címke formában. A kulcs értéke kerül az adatbázisba, és " +"ennek meg kell felelnie az adatbázisban tárolt típussal (%type). A " +"címke nem kötelező, ha nincs megadva, akkor a kulcs kerül " +"felhasználásra, mint címke.<br />Engedélyezett HTML elemek: @tags" + +#: number.module:150 +msgid "" +"Advanced usage only: PHP code that returns a keyed array of allowed " +"values. Should not include <?php ?> delimiters. If this field is " +"filled out, the array returned by this code will override the allowed " +"values list above." +msgstr "" +"Csak haladóknak: PHP kód, ami visszaadja a megengedett értékek " +"tömbjét. Nem szükséges <?php ?> elemek közé zárni. Ha ez " +"a mező ki van töltve, a kód által visszaadott tömb felülír " +"minden fentebb megadott értéket." + +#: number.module:158 +msgid "" +"This PHP code was set by an administrator and will override the " +"allowed values list above." +msgstr "" +"Ezt a PHP kódot egy adminisztrátor állította be, és felül fogja " +"írni a fentebb megadott elfogadható értékek listáját." + +#: number.module:210 +msgid "\"Minimum\" must be a number." +msgstr "„Minimum”-nak számot kell megadni." + +#: number.module:217 +msgid "\"Maximum\" must be a number." +msgstr "„Maximum”-nak számot kell megadni." + +#: number.module:234 +msgid "%name: the value may be no smaller than %min." +msgstr "%name: az érték nem lehet kisebb ennél: %min." + +#: number.module:237 +msgid "%name: the value may be no larger than %max." +msgstr "%name: az érték nem lehet nagyobb ennél: %max." + +#: number.module:250 +msgid "%name: illegal value." +msgstr "%name: érvénytelen érték." + +#: number.module:285 +msgid "unformatted" +msgstr "formázatlan" + +#: number.module:368 +msgid "Text field" +msgstr "Szöveg mező" + +#: number.module:524 +msgid "" +"Only numbers and decimals are allowed in %field. %start was changed to " +"%value." +msgstr "" +"%field: csak számok és tizedesek bevitele megengedett. %start új " +"értéke: %value." + +#: number.module:546 +msgid "Only numbers are allowed in %field. %start was changed to %value." +msgstr "" +"%field: csak számok bevitele megengedett. %start új értéke: " +"%value." + +#: number.module:569 +msgid "" +"Only numbers and the decimal character (%decimal) are allowed in " +"%field. %start was changed to %value." +msgstr "" +"%field: csak számok és a tizedespont (%decimal) bevitele " +"megengedett. %start új értéke: %value." + +#: number.module:0 +msgid "number" +msgstr "szám" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.nl.po new file mode 100644 index 0000000000000000000000000000000000000000..c44a4e8ba6793d875ffa9483dd11e9614ec3724a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.nl.po @@ -0,0 +1,214 @@ +# $Id$ +# +# Dutch translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# number.module,v 1.91.2.33 2009/03/16 22:04:07 yched +# number.info,v 1.7 2008/04/23 18:02:16 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-03 14:26+0200\n" +"PO-Revision-Date: 2009-06-03 14:26+0200\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: Dutch <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: number.module:34 +msgid "Integer" +msgstr "Integer" + +#: number.module:35 +msgid "Store a number in the database as an integer." +msgstr "Sla een waarde in de database op als integer." + +#: number.module:38 +msgid "Decimal" +msgstr "Decimaal" + +#: number.module:39 +msgid "Store a number in the database in a fixed decimal format." +msgstr "Sla een waarde in de database op in een decimaal formaat." + +#: number.module:42 +msgid "Float" +msgstr "Float" + +#: number.module:43 +msgid "Store a number in the database in a floating point format." +msgstr "Sla een waarde in de database op als floating point getal." + +#: number.module:57 +msgid "Minimum" +msgstr "Minimum" + +#: number.module:63 +msgid "Maximum" +msgstr "Maximum" + +#: number.module:71 +msgid "Precision" +msgstr "Precisie" + +#: number.module:72 +msgid "The total number of digits to store in the database, including those to the right of the decimal." +msgstr "" +"Het totale aantal cijfers om op te slaan in de database, inclusief de " +"waardes achter de komma." + +#: number.module:78 +msgid "Scale" +msgstr "Schaal" + +#: number.module:79 +msgid "The number of digits to the right of the decimal." +msgstr "Het aantal waardes achter de komma." + +#: number.module:85 +msgid "Decimal marker" +msgstr "Decimaal scheidingsteken" + +#: number.module:86 +msgid "The character users will input to mark the decimal point in forms." +msgstr "" +"Het karakter dat gebruikers zullen gebruiken om de waardes achter de " +"komma aan te geven in formulieren." + +#: number.module:92 +msgid "Prefix" +msgstr "Voorvoegsel" + +#: number.module:95 +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "" +"Geef op wat als voorvoegsel moet worden gebruikt zoals: $ of €. Laat " +"leeg als er geen voorvoegsel moet worden gebruikt. Maak onderscheid " +"tussen enkelvoud en meervoud met een pipe, bijvoorbeeld: euro|euro's." + +#: number.module:99 +msgid "Suffix" +msgstr "Achtervoegsel" + +#: number.module:102 +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "" +"Geef op wat als achtervoegsel moet worden gebruikt zoals: m², m/s², " +"kb/s. Laat leeg als er geen achtervoegsel moet worden gebruikt. Maak " +"onderscheid tussen enkelvoud en meervoud met een pipe, bijvoorbeeld: " +"kilo|kilo's." + +#: number.module:106 +msgid "Allowed values" +msgstr "Toegestane waardes" + +#: number.module:112 +msgid "Allowed values list" +msgstr "Lijst met toegestane waardes" + +#: number.module:116 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "" +"De mogelijke waardes die in dit veld kunnen staan. Voer één waarde " +"per regel in, in het formaat sleutel|label. De sleutel wordt in de " +"database opgeslagen en moet overeen komen met het veldopslagtype " +"(%type). Het label is optioneel. Als geen label wordt ingevoerd zal de " +"sleutel ook worden gebruikt als label. <br />Toegestane HTML-tags: " +"@tags" + +#: number.module:120 +msgid "PHP code" +msgstr "PHP code" + +#: number.module:127;136 +msgid "Code" +msgstr "Code" + +#: number.module:130 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "" +"Alleen voor geavanceerd gebruik: PHP-code die een array met sleutels " +"geeft van de toegestane waardes. Moet niet beginnen en eindigen met " +"<?php ?>. Als dit veld in ingevuld zullen de bovenstaande " +"toegestane waardes worden genegeerd." + +#: number.module:137 +msgid "<none>" +msgstr "<geen>" + +#: number.module:138 +msgid "You're not allowed to input PHP code." +msgstr "Je mag geen PHP-code gebruiken." + +#: number.module:138 +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "" +"Deze PHP-code is door een beheerder ingesteld en zal worden uitgevoerd " +"in plaats van de toegestane waardeslijst hierboven." + +#: number.module:178 +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Toegestane waardes" + +#: number.module:195 +msgid "\"Minimum\" must be a number." +msgstr "\"Minimum\" moet een nummer zijn." + +#: number.module:202 +msgid "\"Maximum\" must be a number." +msgstr "\"Maximum\" moet een nummer zijn." + +#: number.module:219 +msgid "%name: the value may be no smaller than %min." +msgstr "%name: de waarde mag niet kleiner zijn dan %min." + +#: number.module:222 +msgid "%name: the value may be no larger than %max." +msgstr "%name: de waarde mag niet groter zijn dan %max." + +#: number.module:235 +msgid "%name: illegal value." +msgstr "%name: niet toegestane waarde." + +#: number.module:270 +msgid "unformatted" +msgstr "ongeformatteerd" + +#: number.module:353 +msgid "Text field" +msgstr "Tekstveld" + +#: number.module:512 +msgid "Only numbers and decimals are allowed in %field." +msgstr "Alleen nummers en decimalen zijn toegestaan in %field." + +#: number.module:535 +msgid "Only numbers are allowed in %field." +msgstr "Alleen nummers zijn toegestaan in %field." + +#: number.module:559 +msgid "Only numbers and the decimal character (%decimal) are allowed in %field." +msgstr "" +"Alleen nummers en het decimalenkarakter (%decimal) zijn toegestaan in " +"%field." + +#: number.module:0 +msgid "number" +msgstr "getal" + +#: number.info:0 +msgid "Number" +msgstr "Nummer" + +#: number.info:0 +msgid "Defines numeric field types." +msgstr "Levert numerieke veldtypes." + +#: number.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.pot new file mode 100644 index 0000000000000000000000000000000000000000..a9c136e41d62470cead6695161775262c4c938c5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.pot @@ -0,0 +1,137 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-number) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# number.module,v 1.91.2.35 2009/04/29 20:51:53 karens +# number.info,v 1.7 2008/04/23 18:02:16 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/number/number.module:34 +msgid "Integer" +msgstr "" + +#: modules/number/number.module:35 +msgid "Store a number in the database as an integer." +msgstr "" + +#: modules/number/number.module:39 +msgid "Decimal" +msgstr "" + +#: modules/number/number.module:40 +msgid "Store a number in the database in a fixed decimal format." +msgstr "" + +#: modules/number/number.module:44 +msgid "Float" +msgstr "" + +#: modules/number/number.module:45 +msgid "Store a number in the database in a floating point format." +msgstr "" + +#: modules/number/number.module:60 +msgid "Minimum" +msgstr "" + +#: modules/number/number.module:66 +msgid "Maximum" +msgstr "" + +#: modules/number/number.module:74 +msgid "Precision" +msgstr "" + +#: modules/number/number.module:75 +msgid "The total number of digits to store in the database, including those to the right of the decimal." +msgstr "" + +#: modules/number/number.module:81 +msgid "Scale" +msgstr "" + +#: modules/number/number.module:82 +msgid "The number of digits to the right of the decimal." +msgstr "" + +#: modules/number/number.module:88 +msgid "Decimal marker" +msgstr "" + +#: modules/number/number.module:89 +msgid "The character users will input to mark the decimal point in forms." +msgstr "" + +#: modules/number/number.module:95 +msgid "Prefix" +msgstr "" + +#: modules/number/number.module:98 +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "" + +#: modules/number/number.module:102 +msgid "Suffix" +msgstr "" + +#: modules/number/number.module:105 +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "" + +#: modules/number/number.module:198 +msgid "\"Minimum\" must be a number." +msgstr "" + +#: modules/number/number.module:205 +msgid "\"Maximum\" must be a number." +msgstr "" + +#: modules/number/number.module:222 +msgid "%name: the value may be no smaller than %min." +msgstr "" + +#: modules/number/number.module:225 +msgid "%name: the value may be no larger than %max." +msgstr "" + +#: modules/number/number.module:273 +msgid "unformatted" +msgstr "" + +#: modules/number/number.module:515 +msgid "Only numbers and decimals are allowed in %field." +msgstr "" + +#: modules/number/number.module:538 +msgid "Only numbers are allowed in %field." +msgstr "" + +#: modules/number/number.module:562 +msgid "Only numbers and the decimal character (%decimal) are allowed in %field." +msgstr "" + +#: modules/number/number.module:0 +msgid "number" +msgstr "" + +#: modules/number/number.info:0 +msgid "Number" +msgstr "" + +#: modules/number/number.info:0 +msgid "Defines numeric field types." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..46dc779809cb0fd0fd1c70696e783b398d0cfca8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.sv.po @@ -0,0 +1,190 @@ +# $Id$ +# +# Swedish translation of Drupal (number) +# Generated from files: +# number.module,v 1.91.2.35 2009/04/29 20:51:53 karens +# number.info,v 1.7 2008/04/23 18:02:16 dww +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Number 6.x\n" +"POT-Creation-Date: 2009-05-27 13:47+0200\n" +"PO-Revision-Date: 2009-05-27 14:20+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: number.module:34 +msgid "Integer" +msgstr "Heltal" + +#: number.module:35 +msgid "Store a number in the database as an integer." +msgstr "Lagra ett tal i databasen som ett heltal." + +#: number.module:39 +msgid "Decimal" +msgstr "Decimaltal" + +#: number.module:40 +msgid "Store a number in the database in a fixed decimal format." +msgstr "Lagra ett tal i databasen som ett bestämt format för decimaltal." + +#: number.module:44 +msgid "Float" +msgstr "Flyttal" + +#: number.module:45 +msgid "Store a number in the database in a floating point format." +msgstr "Lagra ett tal i databasen som ett flytande format för tal." + +#: number.module:60 +msgid "Minimum" +msgstr "Lägsta" + +#: number.module:66 +msgid "Maximum" +msgstr "Högsta" + +#: number.module:74 +msgid "Precision" +msgstr "Precision" + +#: number.module:75 +msgid "The total number of digits to store in the database, including those to the right of the decimal." +msgstr "Det totala antalet siffror att lagra i databasen, inklusive de till höger om decimalkommat." + +#: number.module:81 +msgid "Scale" +msgstr "Skala" + +#: number.module:82 +msgid "The number of digits to the right of the decimal." +msgstr "Antalet siffror till höger om decimalkommat." + +#: number.module:88 +msgid "Decimal marker" +msgstr "Decimalmärke" + +#: number.module:89 +msgid "The character users will input to mark the decimal point in forms." +msgstr "Tecken användare kommer att mata in för att markera decimalpunkten i formulär." + +#: number.module:95 +msgid "Prefix" +msgstr "Prefix" + +#: number.module:98 +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Definiera en sträng som skall sättas in före värdet, till exempel $ eller €. Utelämna för tomt värde. Separera enstaka och flerfaldiga värden med en stående streck (krona|kronor)." + +#: number.module:102 +msgid "Suffix" +msgstr "Suffix" + +#: number.module:105 +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Definiera en sträng som skall sättas in efter värdet, såsom m², m/s², kb/s. Utelämna för tomt värde. Separera enstaka och flervärdiga värden med ett stående streck (krona|kronor)." + +#: number.module:109 +msgid "Allowed values" +msgstr "Tillåtna värden" + +#: number.module:115 +msgid "Allowed values list" +msgstr "Tillåtna listvärden" + +#: number.module:119 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "De möjliga värdena detta fält kan innehålla. Ange ett värde per rad i formatet nyckel/etikett. Denna nyckel är värdet som kommer att lagras i databasen och måste överensstämma typen för fältlagring (%type). Etikett är valfritt, och nyckeln som kommer att användas är etiketten om ingen etikett är specificerad.<br />Tillåtna HTML-taggar: @tags" + +#: number.module:123 +msgid "PHP code" +msgstr "PHP-kod" + +#: number.module:130;139 +msgid "Code" +msgstr "Kod" + +#: number.module:133 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Enbart avancerat användande: PHP-kod som skall returnera en spärrad lista av tillåtna värden. Skall inte inkludera avgränsarna <?php ?>. Om detta fält är ifyllt kommer listan som returneras av denna kod att åsidosätta det tillåtna värdet i listan ovan." + +#: number.module:140 +msgid "<none>" +msgstr "<ingen>" + +#: number.module:141 +msgid "You're not allowed to input PHP code." +msgstr "Du har inte tillåtelse att mata in PHP-kod." + +#: number.module:141 +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "Denna PHP-kod angavs av en administratör och kommer att åsidosätta det tillåtna värdet ovan." + +#: number.module:181 +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Tillåtna värden" + +#: number.module:198 +msgid "\"Minimum\" must be a number." +msgstr "\"Lägsta\" måste vara ett tal." + +#: number.module:205 +msgid "\"Maximum\" must be a number." +msgstr "\"Högsta\" måste vara ett tal." + +#: number.module:222 +msgid "%name: the value may be no smaller than %min." +msgstr "%name: värdet får inte vara mindre än %min." + +#: number.module:225 +msgid "%name: the value may be no larger than %max." +msgstr "%name: värdet får inte större än %max." + +#: number.module:238 +msgid "%name: illegal value." +msgstr "%name: otillåtet värde." + +#: number.module:273 +msgid "unformatted" +msgstr "oformaterad" + +#: number.module:356 +msgid "Text field" +msgstr "Textfält" + +#: number.module:515 +msgid "Only numbers and decimals are allowed in %field." +msgstr "Enbart sifror och decimaltal är tillåtna i %field." + +#: number.module:538 +msgid "Only numbers are allowed in %field." +msgstr "Enbart siffror är tillåtna i %field." + +#: number.module:562 +msgid "Only numbers and the decimal character (%decimal) are allowed in %field." +msgstr "Enbart siffror och decimaltalstecken (%decimal) är tillåtna i %field." + +#: number.module:0 +msgid "number" +msgstr "number" + +#: number.info:0 +msgid "Number" +msgstr "Nummer" + +#: number.info:0 +msgid "Defines numeric field types." +msgstr "Definierar numeriska fälttyper." + +#: number.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..d758d5590cbb4cc51f4b38556956236baaf49713 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.help.ini @@ -0,0 +1,11 @@ +; $Id$ + +[advanced help settings] +hide = TRUE + +[overview] +title = Overview + +[optionwidgets] +title = Optionwidgets +parent = content%fields diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.html new file mode 100644 index 0000000000000000000000000000000000000000..c7f444f424e673462a5743319fc371ed1876de1b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.html @@ -0,0 +1,2 @@ +<p>Optionwidgets creates drop-down select lists, checkboxes, and radio widgets that can be used with fields that have specific allowed values.</p> +<p>The <a href="&topic:number/number&">Number</a> and <a href="&topic:text/text&">Text</a> fields have settings for creating lists of allowed values that can be used in Optionwidgets. The <a href="&topic:nodereference/nodereference&">Nodereference</a> and <a href="&topic:userreference/userreference&">Userreference</a> fields use Optionwidgets to present the possible values in select lists or checkboxes.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.info new file mode 100644 index 0000000000000000000000000000000000000000..aac00fd57c444a6bb6d5eac28c80944d9bcb3df6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.info @@ -0,0 +1,12 @@ +; $Id$ +name = Option Widgets +description = Defines selection, check box and radio button widgets for text and numeric fields. +dependencies[] = content +package = CCK +core = 6.x +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.install new file mode 100644 index 0000000000000000000000000000000000000000..5b905649b752e5e2db56447012ead1161c6175fd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.install @@ -0,0 +1,76 @@ +<?php +// $Id$ + +/** + * @file + * Implementation of hook_install(). + */ +function optionwidgets_install() { + drupal_load('module', 'content'); + content_notify('install', 'optionwidgets'); +} + +/** + * Implementation of hook_uninstall(). + */ +function optionwidgets_uninstall() { + drupal_load('module', 'content'); + content_notify('uninstall', 'optionwidgets'); +} + +/** + * Implementation of hook_enable(). + * + * Notify content module when this module is enabled. + */ +function optionwidgets_enable() { + drupal_load('module', 'content'); + content_notify('enable', 'optionwidgets'); +} + +/** + * Implementation of hook_disable(). + * + * Notify content module when this module is disabled. + */ +function optionwidgets_disable() { + drupal_load('module', 'content'); + content_notify('disable', 'optionwidgets'); +} + +function optionwidgets_update_last_removed() { + return 1; +} + +/** + * Rename widgets from 'options_xxx' to 'optionwidgets_xxx' so hook_elements + * and hook_themes items are prefixed with module name as they should be. + * + * The change in widget types will keep content_update_6000() from correctly updating + * the module names in the field and instance tables, so do it here. + */ +function optionwidgets_update_6000() { + if ($abort = content_check_update('optionwidgets')) { + return $abort; + } + + $ret = array(); + + drupal_load('module', 'content'); + $ret[] = update_sql("UPDATE {". content_instance_tablename() ."} SET widget_type = 'optionwidgets_select' WHERE widget_type = 'options_select'"); + $ret[] = update_sql("UPDATE {". content_instance_tablename() ."} SET widget_type = 'optionwidgets_onoff' WHERE widget_type = 'options_onoff'"); + $ret[] = update_sql("UPDATE {". content_instance_tablename() ."} SET widget_type = 'optionwidgets_buttons' WHERE widget_type = 'options_buttons'"); + + content_associate_fields('optionwidgets'); + return $ret; +} + +/** + * Update 6000 was possibly broken if it was executed while + * the modules were still disabled, so we re-run it. + * Having it run a second time on sites that got updated correctly has no + * side-effect (see http://drupal.org/node/310873). + */ +function optionwidgets_update_6001() { + return optionwidgets_update_6000(); +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.module new file mode 100644 index 0000000000000000000000000000000000000000..6ddddef7f25b132f0780ea0872d278d95ff28607 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.module @@ -0,0 +1,456 @@ +<?php +// $Id$ + +/** + * @file + * Defines selection, check box and radio button widgets for text and numeric fields. + */ + +/** + * Implementation of hook_form_alter. + */ +function optionwidgets_form_alter(&$form, $form_state, $form_id) { + // Provide additional help for the field settings form. + if ($form_id == 'content_field_edit_form' && isset($form['widget'])) { + $widget_type = $form['#field']['widget']['type']; + $field_type = $form['#field']['type']; + $label = $form['#field']['widget']['label']; + + $output = '<p>'. t('Create a list of options as a list in <strong>Allowed values list</strong> or as an array in PHP code. These values will be the same for %field in all content types.', array('%field' => $label)) .'</p>'; + + if ($widget_type == 'optionwidgets_onoff') { + $output .= '<p>'. t("For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value.") .'</p>'; + } + elseif ($widget_type == 'optionwidgets_buttons') { + $output .= '<p>'. t("The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed.") .'</p>'; + } + + if (in_array($field_type, array('text', 'number_integer', 'number_float', 'number_decimal')) + && in_array($widget_type, array('optionwidgets_onoff', 'optionwidgets_buttons', 'optionwidgets_select'))) { + $form['field']['allowed_values_fieldset']['#collapsed'] = FALSE; + $form['field']['allowed_values_fieldset']['#description'] = $output; + + // If no 'allowed values' were set yet, add a remainder in the messages area. + if (empty($form_state['post']) + && empty($form['field']['allowed_values_fieldset']['allowed_values']['#default_value']) + && empty($form['field']['allowed_values_fieldset']['advanced_options']['allowed_values_php']['#default_value'])) { + drupal_set_message(t("You need to specify the 'allowed values' for this field."), 'warning'); + } + } + } +} + +/** + * Implementation of hook_theme(). + */ +function optionwidgets_theme() { + return array( + 'optionwidgets_select' => array( + 'arguments' => array('element' => NULL), + ), + 'optionwidgets_buttons' => array( + 'arguments' => array('element' => NULL), + ), + 'optionwidgets_onoff' => array( + 'arguments' => array('element' => NULL), + ), + 'optionwidgets_none' => array( + 'arguments' => array('widget_type' => NULL, 'field_name' => NULL, 'node_type' => NULL), + ), + ); +} + +/** + * Implementation of hook_widget_info(). + * + * We need custom handling of multiple values because we need + * to combine them into a options list rather than display + * multiple elements. We will use the content module's default + * handling for default values. + * + * Callbacks can be omitted if default handing is used. + * They're included here just so this module can be used + * as an example for custom modules that might do things + * differently. + */ +function optionwidgets_widget_info() { + + return array( + 'optionwidgets_select' => array( + 'label' => t('Select list'), + 'field types' => array('text', 'number_integer', 'number_decimal', 'number_float'), + 'multiple values' => CONTENT_HANDLE_MODULE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + 'optionwidgets_buttons' => array( + 'label' => t('Check boxes/radio buttons'), + 'field types' => array('text', 'number_integer', 'number_decimal', 'number_float'), + 'multiple values' => CONTENT_HANDLE_MODULE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + 'optionwidgets_onoff' => array( + 'label' => t('Single on/off checkbox'), + 'field types' => array('text', 'number_integer', 'number_decimal', 'number_float'), + 'multiple values' => CONTENT_HANDLE_MODULE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + ); +} + +/** + * Implementation of FAPI hook_elements(). + * + * Any FAPI callbacks needed for individual widgets can be declared here, + * and the element will be passed to those callbacks for processing. + * + * Drupal will automatically theme the element using a theme with + * the same name as the hook_elements key. + */ +function optionwidgets_elements() { + return array( + 'optionwidgets_select' => array( + '#input' => TRUE, + '#columns' => array('value'), '#delta' => 0, + '#process' => array('optionwidgets_select_process'), + ), + 'optionwidgets_buttons' => array( + '#input' => TRUE, + '#columns' => array('value'), '#delta' => 0, + '#process' => array('optionwidgets_buttons_process'), + ), + 'optionwidgets_onoff' => array( + '#input' => TRUE, + '#columns' => array('value'), '#delta' => 0, + '#process' => array('optionwidgets_onoff_process'), + ), + ); +} + +/** + * Implementation of hook_widget(). + * + * Attach a single form element to the form. It will be built out and + * validated in the callback(s) listed in hook_elements. We build it + * out in the callbacks rather than here in hook_widget so it can be + * plugged into any module that can provide it with valid + * $field information. + * + * Content module will set the weight, field name and delta values + * for each form element. This is a change from earlier CCK versions + * where the widget managed its own multiple values. + * + * If there are multiple values for this field, the content module will + * call this function as many times as needed. + * + * @param $form + * the entire form array, $form['#node'] holds node information + * @param $form_state + * the form_state, $form_state['values'][$field['field_name']] + * holds the field's form values. + * @param $field + * the field array + * @param $items + * an array of default values for this element + * @param $delta + * the order of this item in the array of subelements (0, 1, 2, etc) + * + * @return + * the form item for a single element for this field + */ +function optionwidgets_widget(&$form, &$form_state, $field, $items, $delta = NULL) { + $element = array( + '#type' => $field['widget']['type'], + '#default_value' => !empty($items) ? $items : array(), + ); + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function optionwidgets_buttons_process($element, $edit, &$form_state, $form) { + $field_name = $element['#field_name']; + $field = $form['#field_info'][$field_name]; + $field_key = $element['#columns'][0]; + + // See if this element is in the database format or the transformed format, + // and transform it if necessary. + if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) { + $element['#value'] = optionwidgets_data2form($element, $element['#default_value'], $field); + } + $options = optionwidgets_options($field); + $element[$field_key] = array( + '#type' => $field['multiple'] ? 'checkboxes' : 'radios', + '#title' => $element['#title'], + '#description' => $element['#description'], + '#required' => isset($element['#required']) ? $element['#required'] : $field['required'], + '#multiple' => isset($element['#multiple']) ? $element['#multiple'] : $field['multiple'], + '#options' => $options, + '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, + ); + + // Set #element_validate in a way that it will not wipe out other + // validation functions already set by other modules. + if (empty($element['#element_validate'])) { + $element['#element_validate'] = array(); + } + array_unshift($element['#element_validate'], 'optionwidgets_validate'); + + // Make sure field info will be available to the validator which + // does not get the values in $form. + $form_state['#field_info'][$field['field_name']] = $field; + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function optionwidgets_select_process($element, $edit, &$form_state, $form) { + $field_name = $element['#field_name']; + $field = $form['#field_info'][$field_name]; + $field_key = $element['#columns'][0]; + + // See if this element is in the database format or the transformed format, + // and transform it if necessary. + if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) { + $element['#value'] = optionwidgets_data2form($element, $element['#default_value'], $field); + } + + $options = optionwidgets_options($field, FALSE); + + // For this specific widget, HTML should be filtered out and entities left unencoded. + // See content_allowed_values / content_filter_xss / filter_xss. + content_allowed_values_filter_html($options); + + $element[$field_key] = array( + '#type' => 'select', + '#title' => $element['#title'], + '#description' => $element['#description'], + '#required' => isset($element['#required']) ? $element['#required'] : $field['required'], + '#multiple' => isset($element['#multiple']) ? $element['#multiple'] : $field['multiple'], + '#options' => $options, + '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, + ); + + // Set #element_validate in a way that it will not wipe out other + // validation functions already set by other modules. + if (empty($element['#element_validate'])) { + $element['#element_validate'] = array(); + } + array_unshift($element['#element_validate'], 'optionwidgets_validate'); + + // Make sure field info will be available to the validator which + // does not get the values in $form. + + // TODO for some reason putting the $field array into $form_state['storage'] + // causes the node's hook_form_alter to be invoked twice, garbling the + // results. Need to investigate why that is happening (a core bug?), but + // in the meantime avoid using $form_state['storage'] to store anything. + $form_state['#field_info'][$field['field_name']] = $field; + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function optionwidgets_onoff_process($element, $edit, &$form_state, $form) { + $field_name = $element['#field_name']; + $field = $form['#field_info'][$field_name]; + $field_key = $element['#columns'][0]; + + // See if this element is in the database format or the transformed format, + // and transform it if necessary. + if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) { + $element['#value'] = optionwidgets_data2form($element, $element['#default_value'], $field); + } + $options = optionwidgets_options($field); + $keys = array_keys($options); + $on_value = (!empty($keys) && isset($keys[1])) ? $keys[1] : NULL; + $element[$field_key] = array( + '#type' => 'checkbox', + '#title' => isset($options[$on_value]) ? $options[$on_value] : '', + '#description' => $element['#description'], + '#required' => isset($element['#required']) ? $element['#required'] : $field['required'], + '#default_value' => isset($element['#value'][$field_key][0]) ? $element['#value'][$field_key][0] == $on_value : FALSE, + '#return_value' => $on_value, + ); + + // Set #element_validate in a way that it will not wipe out other + // validation functions already set by other modules. + if (empty($element['#element_validate'])) { + $element['#element_validate'] = array(); + } + array_unshift($element['#element_validate'], 'optionwidgets_validate'); + + // Make sure field info will be available to the validator which + // does not get the values in $form. + $form_state['#field_info'][$field['field_name']] = $field; + return $element; +} + +/** + * FAPI function to validate optionwidgets element. + */ +function optionwidgets_validate($element, &$form_state) { + // Transpose selections from field => delta to delta => field, + // turning multiple selected options into multiple parent elements. + // Immediate parent is the delta, need to get back to parent's parent + // to create multiple elements. + $field = $form_state['#field_info'][$element['#field_name']]; + $items = optionwidgets_form2data($element, $field); + form_set_value($element, $items, $form_state); + + // Check we don't exceed the allowed number of values. + if ($field['multiple'] >= 2) { + // Filter out 'none' value (if present, will always be in key 0) + $field_key = $element['#columns'][0]; + if (isset($items[0][$field_key]) && $items[0][$field_key] === '') { + unset($items[0]); + } + if (count($items) > $field['multiple']) { + $field_key = $element['#columns'][0]; + form_error($element[$field_key], t('%name: this field cannot hold more than @count values.', array('%name' => t($field['widget']['label']), '@count' => $field['multiple']))); + } + } +} + +/** + * Helper function to transpose the values as stored in the database + * to the format the widget needs. Can be called anywhere this + * transformation is needed. + */ +function optionwidgets_data2form($element, $items, $field) { + $field_key = $element['#columns'][0]; + $options = optionwidgets_options($field); + + $items_transposed = content_transpose_array_rows_cols($items); + $values = (isset($items_transposed[$field_key]) && is_array($items_transposed[$field_key])) ? $items_transposed[$field_key] : array(); + $keys = array(); + foreach ($values as $value) { + $key = array_search($value, array_keys($options)); + if (isset($key)) { + $keys[] = $value; + } + } + if ($field['multiple'] || $element['#type'] == 'optionwidgets_onoff') { + return array($field_key => $keys); + } + else { + return !empty($keys) ? array($field_key => $value) : array(); + } +} + +/** + * Helper function to transpose the values returned by submitting the widget + * to the format to be stored in the field. Can be called anywhere this + * transformation is needed. + */ +function optionwidgets_form2data($element, $field) { + $field_key = $element['#columns'][0]; + $items = (array) $element[$field_key]['#value']; + $options = optionwidgets_options($field); + + $values = array_values($items); + + if ($element['#type'] == 'optionwidgets_onoff' && ($values[0] === 0)) { + $keys = array_keys($options); + $values = array(array_key_exists(0, $keys) ? $keys[0] : NULL); + } + + if (empty($values)) { + $values[] = NULL; + } + $result = content_transpose_array_rows_cols(array($field_key => $values)); + return $result; +} + +/** + * Helper function for finding the allowed values list for a field. + * + * See if there is a module hook for the option values. + * Otherwise, try content_allowed_values() for an options list. + * + * @param $field + * The field whose allowed values are requested. + * @param $flatten + * Optional. Use TRUE to return a flattened array (default). + * FALSE can be used to support optgroups for select widgets + * when allowed values list is generated using PHP code. + */ +function optionwidgets_options($field, $flatten = TRUE) { + $function = $field['module'] .'_allowed_values'; + $options = function_exists($function) ? $function($field) : (array) content_allowed_values($field, $flatten); + // Add an empty choice for : + // - non required radios + // - non required selects + if (!$field['required']) { + if ((in_array($field['widget']['type'], array('optionwidgets_buttons', 'nodereference_buttons', 'userreference_buttons')) && !$field['multiple']) + || (in_array($field['widget']['type'], array('optionwidgets_select', 'nodereference_select', 'userreference_select')))) { + $options = array('' => theme('optionwidgets_none', $field)) + $options; + } + } + return $options; +} + +/** + * Theme the label for the empty value for options that are not required. + * The default theme will display N/A for a radio list and blank for a select. + */ +function theme_optionwidgets_none($field) { + switch ($field['widget']['type']) { + case 'optionwidgets_buttons': + case 'nodereference_buttons': + case 'userreference_buttons': + return t('N/A'); + case 'optionwidgets_select': + case 'nodereference_select': + case 'userreference_select': + return t('- None -'); + default : + return ''; + } +} + +/** + * FAPI themes for optionwidgets. + * + * The select, checkboxes or radios are already rendered by the + * select, checkboxes, or radios themes and the HTML output + * lives in $element['#children']. Override this theme to + * make custom changes to the output. + * + * $element['#field_name'] contains the field name + * $element['#delta] is the position of this element in the group + */ +function theme_optionwidgets_select($element) { + return $element['#children']; +} + +function theme_optionwidgets_onoff($element) { + return $element['#children']; +} + +function theme_optionwidgets_buttons($element) { + return $element['#children']; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.de.po new file mode 100644 index 0000000000000000000000000000000000000000..43ae44cee830213f3e1e7e9ea3f06df371fc6a0d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.de.po @@ -0,0 +1,79 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2008-11-05 12:54+0100\n" +"PO-Revision-Date: 2008-11-05 13:34+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/optionwidgets/optionwidgets.module:19 +msgid "Create a list of options as a list in <strong>Allowed values list</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "Eine Liste von Optionen als Liste in der <strong>zulässigen Werteliste</strong> oder als ein Array in PHP-Code erstellen. Diese Werte werden für %field in allen Inhaltsstypen gleich sein." + +#: modules/optionwidgets/optionwidgets.module:22 +msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "Für ein einzelnes „an/aus“ Ankreuzfeld-Steuerelement sollte zuerst der ‚aus‘ Wert und dann der ‚an‘ Wert im Bereich der <strong>gültigen Werte</strong> angegeben werden. Das Ankreuzfeld wird mit der Beschriftung des ‚an‘ Wertes beschriftet." + +#: modules/optionwidgets/optionwidgets.module:25 +msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "Das ‚Ankreuzfeld/Auswahlknöpfe‘-Steuerelement wird Ankreuzfelder anzeigen, wenn die Option für mehrere Werte bei diesem Feld ausgewählt wurde, ansonsten werden Auswahlknöpfe anzeigt." + +#: modules/optionwidgets/optionwidgets.module:37 +msgid "You need to specify the 'allowed values' for this field." +msgstr "Für dieses Feld müssen die „zulässigen Werte“ angegeben werden." + +#: modules/optionwidgets/optionwidgets.module:96 +msgid "Single on/off checkbox" +msgstr "Einzelnes an/aus Ankreuzfeld" + +#: modules/optionwidgets/optionwidgets.module:326 +msgid "%name: this field cannot hold more than @count values." +msgstr "%name: Dieses Feld kann nicht mehr als @count Werte enthalten." + +#: modules/optionwidgets/optionwidgets.module:411 +msgid "N/A" +msgstr "k.A." + +#: modules/optionwidgets/optionwidgets.module:415 +msgid "- None -" +msgstr "- Keine -" + +#: modules/optionwidgets/optionwidgets.module:0 +msgid "optionwidgets" +msgstr "Options-Steuerelemente" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Options-Steuerelemente" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "Definiert Auswahlfeld-, Ankreuzfeld- und Auswahlknopf-Steuerelemente für Texte und numerische Felder." + +#: modules/text/text.module:41 +#: modules/text/text.info:0 +msgid "Text" +msgstr "Text" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..c02d63bb2b1f695a9f9d94207dea2bc10d23add2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.fr.po @@ -0,0 +1,75 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 13:24+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: modules/optionwidgets/optionwidgets.module:10 +msgid "" +"Create a list of options as a list in <strong>Allowed values</strong> or as " +"an array in PHP code. These values will be the same for %field in all " +"content types." +msgstr "" +"Créez une liste d'options en tant que liste dans les <strong>Valeurs " +"permises</strong> ou en tant que tableau dans le code PHP. Ces valeurs " +"seront identiques pour '%field' dans tous les types de contenus." + +#: modules/optionwidgets/optionwidgets.module:12 +msgid "" +"For a 'single on/off checkbox' widget, define the 'off' value first, then " +"the 'on' value in the <strong>Allowed values</strong> section. Note that the " +"checkbox will be labeled with the label of the 'on' value." +msgstr "" +"Pour un widget 'case à cocher on/off unique', définissez d'abord la valeur " +"'off' puis la valeur 'on' dans la section <strong>Valeurs permises</strong>. " +"Notez que l'intitulé de la case à cocher sera celui de la valeur 'on'." + +#: modules/optionwidgets/optionwidgets.module:15 +msgid "" +"The 'checkboxes/radio buttons' widget will display checkboxes if the " +"multiple values option is selected for this field, otherwise radios will be " +"displayed." +msgstr "" +"Le widget 'cases à cocher/bouton radio' fera apparaître des cases à cocher " +"si l'option 'valeurs multiples' est sélectionnée pour ce champ ; dans le cas " +"contraire, ce seront des boutons radio." + +#: modules/optionwidgets/optionwidgets.module:70 +msgid "Check boxes/radio buttons" +msgstr "Cases à cocher/boutons radio" + +#: modules/optionwidgets/optionwidgets.module:78 +msgid "Single on/off checkbox" +msgstr "Case à cocher on/off unique" + +#: modules/optionwidgets/optionwidgets.module:364 +msgid "N/A" +msgstr "Non disponible" + +#: modules/optionwidgets/optionwidgets.module:0 +msgid "optionwidgets" +msgstr "optionwidgets" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Option Widgets" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "" +"Defines selection, check box and radio button widgets for text and numeric " +"fields." +msgstr "" +"Permet de créer des widgets de sélection, cases à cocher et boutons radio " +"pour les champs de texte et numériques." diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..f4e15e8757155d9340ed09d5c3012743e63b0123 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.hu.po @@ -0,0 +1,84 @@ +# Hungarian translation of cck (6.x-2.0-rc10) +# Copyright (c) 2008 by the Hungarian translation team +# Generated from files: +# optionwidgets.module,v 1.69.2.18 2008/10/06 15:11:39 karens +# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww +# +msgid "" +msgstr "" +"Project-Id-Version: cck (6.x-2.0-rc10)\n" +"POT-Creation-Date: 2008-10-31 12:16-0500\n" +"PO-Revision-Date: 2008-10-26 11:40-0500\n" +"Last-Translator: Balogh Zoltán\n" +"Language-Team: Drupal.hu Fordítói Csapat <forditas [at] drupal.hu>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: modules/optionwidgets/optionwidgets.module:401 +msgid "- None -" +msgstr "- Nincs -" + +#: modules/optionwidgets/optionwidgets.module:397 +msgid "N/A" +msgstr "N/A" + +#: modules/optionwidgets/optionwidgets.module:19 +msgid "" +"Create a list of options as a list in <strong>Allowed values " +"list</strong> or as an array in PHP code. These values will be the " +"same for %field in all content types." +msgstr "" +"A választható értékek megadása az <strong>Engedélyezett " +"értékek</strong> mezőben, vagy egy PHP kóddal előállított " +"tömbben. Erre a mezőre (%field) vonatkozóan ezek az értékek " +"minden tartalomtípusnál megegyeznek." + +#: modules/optionwidgets/optionwidgets.module:22 +msgid "" +"For a 'single on/off checkbox' widget, define the 'off' value first, " +"then the 'on' value in the <strong>Allowed values</strong> section. " +"Note that the checkbox will be labeled with the label of the 'on' " +"value." +msgstr "" +"Az „egyszerű jelölőnégyzet” felületi elemnél először a " +"„ki”, majd a „be” állapothoz tartozó értéket kell megadni " +"az <strong>Engedélyezett értékek</strong> részben. A " +"jelölőnégyzet címkéje a „be” állapothoz tartozó érték " +"címkéje lesz." + +#: modules/optionwidgets/optionwidgets.module:25 +msgid "" +"The 'checkboxes/radio buttons' widget will display checkboxes if the " +"multiple values option is selected for this field, otherwise radios " +"will be displayed." +msgstr "" +"A „Jelölőnégyzetek/választógombok” felületi elem " +"jelölőnégyzeteket jelenít meg, ha a mezőnek több értéke is " +"lehet, különben választógombok jelennek meg." + +#: modules/optionwidgets/optionwidgets.module:37 +msgid "You need to specify the 'allowed values' for this field." +msgstr "Ki kell tölteni a „Megengedett értékek”-et ennél a mezőnél." + +#: modules/optionwidgets/optionwidgets.module:96 +msgid "Single on/off checkbox" +msgstr "Egyszerű be/ki jelölőnégyzet" + +#: modules/optionwidgets/optionwidgets.module:0 +msgid "optionwidgets" +msgstr "optionwidgets" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Kapcsoló felületi elemek" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "" +"Defines selection, check box and radio button widgets for text and " +"numeric fields." +msgstr "" +"A szöveg és szám mezőtípushoz legördülő lista, " +"jelölőnégyzet és választógomb típusú felületi elemeket ad." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.nl.po new file mode 100644 index 0000000000000000000000000000000000000000..be13b61ddd7e489ca3816a5bde4cc5d794dfc168 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.nl.po @@ -0,0 +1,89 @@ +# $Id$ +# +# Dutch translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# optionwidgets.module,v 1.69.2.23 2009/03/18 21:00:58 yched +# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-03 14:26+0200\n" +"PO-Revision-Date: 2009-06-03 14:26+0200\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: Dutch <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: optionwidgets.module:19 +msgid "Create a list of options as a list in <strong>Allowed values list</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "" +"Maak een lijst met opties als in <strong>Toegestane " +"waardeslijst</strong> of als een array in PHP. Deze waarde zullen " +"hetzelfde zijn in %field in alle inhoudstypes." + +#: optionwidgets.module:22 +msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "" +"Voor een aan/uit vinkjewidget moet je eerst de 'uit'-waarde opgeven en " +"daarna de 'aan'-waarde in de <strong>Toegestane " +"waarde</strong>-sectie. Merk op dat het vinkje zal worden gelabeled " +"met de waarde van 'aan'." + +#: optionwidgets.module:25 +msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "" +"De 'vinkje-/radio button'widget zal een vinkje tonen als de meerdere " +"toegestane waardes is geselecteerd voor dit veld, anders zullen radio " +"buttons worden gebruikt." + +#: optionwidgets.module:37 +msgid "You need to specify the 'allowed values' for this field." +msgstr "Je moet de toegestane waardes voor dit veld opgeven." + +#: optionwidgets.module:80 +msgid "Select list" +msgstr "Selectielijst" + +#: optionwidgets.module:88 +msgid "Check boxes/radio buttons" +msgstr "Vinkje/radio buttons" + +#: optionwidgets.module:96 +msgid "Single on/off checkbox" +msgstr "Een aan/uit vinkje" + +#: optionwidgets.module:331 +msgid "%name: this field cannot hold more than @count values." +msgstr "%name: dit veld kan niet meer dan @count waardes bevatten." + +#: optionwidgets.module:416 +msgid "N/A" +msgstr "Niet beschikbaar" + +#: optionwidgets.module:420 +msgid "- None -" +msgstr "- Geen -" + +#: optionwidgets.module:0 +msgid "optionwidgets" +msgstr "optiewidgets" + +#: optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Optiewidgets" + +#: optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "" +"Levert selectie-, vinkje- en radio buttonwidgets voor tekst- en " +"numerieke velden." + +#: optionwidgets.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.pot new file mode 100644 index 0000000000000000000000000000000000000000..06a70597efaad6f331fde4786503cd63f7d8539d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.pot @@ -0,0 +1,71 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-optionwidgets) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# optionwidgets.module,v 1.69.2.23 2009/03/18 21:00:58 yched +# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww +# text.module,v 1.95.2.29 2009/04/29 20:51:53 karens +# text.info,v 1.9 2008/04/23 18:02:31 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/optionwidgets/optionwidgets.module:19 +msgid "Create a list of options as a list in <strong>Allowed values list</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "" + +#: modules/optionwidgets/optionwidgets.module:22 +msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "" + +#: modules/optionwidgets/optionwidgets.module:25 +msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "" + +#: modules/optionwidgets/optionwidgets.module:37 +msgid "You need to specify the 'allowed values' for this field." +msgstr "" + +#: modules/optionwidgets/optionwidgets.module:96 +msgid "Single on/off checkbox" +msgstr "" + +#: modules/optionwidgets/optionwidgets.module:331 +msgid "%name: this field cannot hold more than @count values." +msgstr "" + +#: modules/optionwidgets/optionwidgets.module:416 +msgid "N/A" +msgstr "" + +#: modules/optionwidgets/optionwidgets.module:420 +msgid "- None -" +msgstr "" + +#: modules/optionwidgets/optionwidgets.module:0 +msgid "optionwidgets" +msgstr "" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "Option Widgets" +msgstr "" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "" + +#: modules/text/text.module:41 modules/text/text.info:0 +msgid "Text" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..99e0dd4ebe5a13f879da77a09f415980a23085af --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.sv.po @@ -0,0 +1,78 @@ +# $Id$ +# +# Swedish translation of Drupal (optionwidgets) +# Generated from files: +# optionwidgets.module,v 1.69.2.23 2009/03/18 21:00:58 yched +# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Optionwidgets 6.x\n" +"POT-Creation-Date: 2009-05-27 13:47+0200\n" +"PO-Revision-Date: 2009-05-27 14:01+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: optionwidgets.module:19 +msgid "Create a list of options as a list in <strong>Allowed values list</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "Skapa en lista av alternativ som en lista i <strong>Tillåtna värden</strong> eller som en lista i PHP-kod. Dessa värden kommer att vara likadana för %field i alla innehållstyper." + +#: optionwidgets.module:22 +msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "För en gränssnittskomponent \"enstaka kryssruta för av/på\", definiera värdet för \"av\" först, sedan värdet för \"på\" i <strong>Tillåtna värden</strong. Observera att kryssrutan kommer att namnges efter etiketten på värdet för \"på\"." + +#: optionwidgets.module:25 +msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "Gränssnittskomponenten för \"kryssrutor/radioknappar\" kommer att visa kryssrutor om flera alternativet flera värden är valt för detta vält, annars kommer radioknappar att visas." + +#: optionwidgets.module:37 +msgid "You need to specify the 'allowed values' for this field." +msgstr "Du måste ange \"tillåtna värden\" för detta fält." + +#: optionwidgets.module:80 +msgid "Select list" +msgstr "Listval" + +#: optionwidgets.module:88 +msgid "Check boxes/radio buttons" +msgstr "Kryssrutor/radioknappar" + +#: optionwidgets.module:96 +msgid "Single on/off checkbox" +msgstr "Enstaka kryssruta för av/på" + +#: optionwidgets.module:331 +msgid "%name: this field cannot hold more than @count values." +msgstr "%name: detta fält kan inte innehålla mer än @count värden." + +#: optionwidgets.module:416 +msgid "N/A" +msgstr "Ej tillgänglig" + +#: optionwidgets.module:420 +msgid "- None -" +msgstr "- Ingen -" + +#: optionwidgets.module:0 +msgid "optionwidgets" +msgstr "optionwidgets" + +#: optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Alternativ för gränssnittskomponent" + +#: optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "Definierar urval, gränssnittskomponenter för kryssrutor och radioknappar för text- och numeriska fält." + +#: optionwidgets.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/help/text.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/help/text.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..464c3f73c4145332df1c2b52926f3e563156987d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/help/text.help.ini @@ -0,0 +1,8 @@ +; $Id$ + +[advanced help settings] +hide = TRUE + +[text] +title = Text field +parent = content%fields diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/help/text.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/help/text.html new file mode 100644 index 0000000000000000000000000000000000000000..e5a1f6acfc2d4b80d98b04ddbc757a613a8f7ae1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/help/text.html @@ -0,0 +1,2 @@ +<p>The Text field stores textual data in the database. It can either be a simple textfield to hold up to 255 characters, or a textarea of an unlimited size that can be combined with input filters to store lengthy descriptions and HTML code.</p> +<p>The Text field provides a place for the administrator to create a list of 'Allowed values' for the field. When used with <a href="&topic:optionwidgets/optionwidgets&">Optionwidgets</a>, the allowed values are presented to the end user in a drop-down select list, checkboxes, or radios.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.info new file mode 100644 index 0000000000000000000000000000000000000000..526f53ab634dc5a4e4ec0efd8aad80bff78c8cc6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.info @@ -0,0 +1,12 @@ +; $Id$ +name = Text +description = Defines simple text field types. +dependencies[] = content +package = CCK +core = 6.x +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.install new file mode 100644 index 0000000000000000000000000000000000000000..a6569c54af4de8db4f5c906dca17dda17c088f44 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.install @@ -0,0 +1,156 @@ +<?php +// $Id$ + +/** + * @file + * Implementation of hook_install(). + */ +function text_install() { + drupal_load('module', 'content'); + content_notify('install', 'text'); +} + +/** + * Implementation of hook_uninstall(). + */ +function text_uninstall() { + drupal_load('module', 'content'); + content_notify('uninstall', 'text'); +} + +/** + * Implementation of hook_enable(). + * + * Notify content module when this module is enabled. + */ +function text_enable() { + drupal_load('module', 'content'); + content_notify('enable', 'text'); +} + +/** + * Implementation of hook_disable(). + * + * Notify content module when this module is disabled. + */ +function text_disable() { + drupal_load('module', 'content'); + content_notify('disable', 'text'); +} + +function text_update_last_removed() { + return 5; +} + +/** + * Rename widgets to match hook_elements values. + * + * The change in field_types will keep content_update_6000() from correctly updating + * the module names in the field and instance tables, so do it here. + * + */ +function text_update_6000() { + if ($abort = content_check_update('text')) { + return $abort; + } + + $ret = array(); + + drupal_load('module', 'content'); + $result = db_query("SELECT * FROM {". content_instance_tablename() ."} WHERE widget_type = 'text'"); + while ($field_instance = db_fetch_array($result)) { + $widget_settings = unserialize($field_instance['widget_settings']); + $new_widget_type = ($widget_settings['rows'] > 1) ? 'text_textarea' : 'text_textfield'; + $ret[] = update_sql("UPDATE {". content_instance_tablename() ."} SET widget_module = 'text', widget_type = '". $new_widget_type ."' WHERE field_name = '{$field_instance['field_name']}' AND type_name = '{$field_instance['type_name']}'"); + } + content_associate_fields('text'); + return $ret; +} + +/** + * Set all columns to accept NULL values and set empty string values in the + * database to NULL. + * + * Leaving it up to module developers to handle conversion of numbers to + * NULL values, since there are times when zeros are valid data and times + * when they should be NULL. + * + */ +function text_update_6001(&$sandbox) { + include_once('./'. drupal_get_path('module', 'content') .'/content.install'); + drupal_load('module', 'content'); + + $ret = array(); + + if (!isset($sandbox['progress'])) { + if ($abort = content_check_update('text')) { + return $abort; + } + + // Get the latest cache values and schema. + content_clear_type_cache(TRUE, TRUE); + $types = content_types_install(); + + if (empty($types)) { + return $ret; + } + + $sandbox['fields'] = array(); + foreach ($types as $type_name => $fields) { + foreach ($fields as $field) { + if ($field['type'] == 'text') { + $sandbox['fields'][] = $field; + } + } + } + + if (empty($sandbox['fields'])) { + return $ret; + } + + $sandbox['progress'] = 0; + $sandbox['visited'] = array(); + } + + $field = $sandbox['fields'][$sandbox['progress']]; + + // We only want to process a field once -- if we hit it a second time, + // that means it's its own table and it should have already been updated. + if (!in_array($field['field_name'], $sandbox['visited'])) { + $db_info = content_database_info($field); + $table = $db_info['table']; + foreach ($db_info['columns'] as $column => $attributes) { + $attributes['not null'] = FALSE; + $column = $attributes['column']; + db_change_field($ret, $table, $column, $column, $attributes); + // TODO: errors on text/blob columns: no default value allowed (!) + db_field_set_no_default($ret, $table, $column); + if ($attributes['type'] == 'varchar' || $attributes['type'] == 'text') { + $ret[] = update_sql("UPDATE {". $table ."} SET ". $column ." = NULL WHERE ". $column ." = ''"); + } + else { + // TODO: replace format = 0 with format = NULL ?? Is this right ? + $ret[] = update_sql("UPDATE {". $table ."} SET ". $column ." = NULL WHERE ". $column ." = 0"); + } + } + $sandbox['visited'][] = $field['field_name']; + } + + $sandbox['progress']++; + $ret['#finished'] = $sandbox['progress'] / count($sandbox['fields']); + + return $ret; +} + +/** + * Update 6000 and 6001 were possibly broken if they were executed while + * the modules were still disabled, so we re-run them. + * Having them run a second time on sites that got updated correctly has no + * side-effect (see http://drupal.org/node/310873). + */ +function text_update_6002() { + return text_update_6000(); +} +function text_update_6003(&$sandbox) { + return text_update_6001($sandbox); +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.module new file mode 100644 index 0000000000000000000000000000000000000000..48585f9827241f21dd65cec22fe507c34088f820 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.module @@ -0,0 +1,485 @@ +<?php +// $Id$ + +/** + * @file + * Defines simple text field types. + */ + +/** + * Implementation of hook_theme(). + */ +function text_theme() { + return array( + 'text_textarea' => array( + 'arguments' => array('element' => NULL), + ), + 'text_textfield' => array( + 'arguments' => array('element' => NULL), + ), + 'text_formatter_default' => array( + 'arguments' => array('element' => NULL), + ), + 'text_formatter_plain' => array( + 'arguments' => array('element' => NULL), + ), + 'text_formatter_trimmed' => array( + 'arguments' => array('element' => NULL), + ), + 'text_formatter_foo' => array( + 'arguments' => array('element' => NULL), + ), + ); +} + +/** + * Implementation of hook_field_info(). + */ +function text_field_info() { + return array( + 'text' => array( + 'label' => t('Text'), + 'description' => t('Store text in the database.'), +// 'content_icon' => 'icon_content_text.png', + ), + ); +} + +/** + * Implementation of hook_field_settings(). + */ +function text_field_settings($op, $field) { + switch ($op) { + case 'form': + $form = array(); + $options = array(0 => t('Plain text'), 1 => t('Filtered text (user selects input format)')); + $form['text_processing'] = array( + '#type' => 'radios', + '#title' => t('Text processing'), + '#default_value' => is_numeric($field['text_processing']) ? $field['text_processing'] : 0, + '#options' => $options, + ); + $form['max_length'] = array( + '#type' => 'textfield', + '#title' => t('Maximum length'), + '#default_value' => is_numeric($field['max_length']) ? $field['max_length'] : '', + '#required' => FALSE, + '#element_validate' => array('_element_validate_integer_positive'), + '#description' => t('The maximum length of the field in characters. Leave blank for an unlimited size.'), + ); + $form['allowed_values_fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Allowed values'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['allowed_values_fieldset']['allowed_values'] = array( + '#type' => 'textarea', + '#title' => t('Allowed values list'), + '#default_value' => !empty($field['allowed_values']) ? $field['allowed_values'] : '', + '#required' => FALSE, + '#rows' => 10, + '#description' => t('The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags', array('%type' => $field['type'], '@tags' => _content_filter_xss_display_allowed_tags())), + ); + $form['allowed_values_fieldset']['advanced_options'] = array( + '#type' => 'fieldset', + '#title' => t('PHP code'), + '#collapsible' => TRUE, + '#collapsed' => empty($field['allowed_values_php']), + ); + if (user_access('Use PHP input for field settings (dangerous - grant with care)')) { + $form['allowed_values_fieldset']['advanced_options']['allowed_values_php'] = array( + '#type' => 'textarea', + '#title' => t('Code'), + '#default_value' => !empty($field['allowed_values_php']) ? $field['allowed_values_php'] : '', + '#rows' => 6, + '#description' => t('Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above.'), + ); + } + else { + $form['allowed_values_fieldset']['advanced_options']['markup_allowed_values_php'] = array( + '#type' => 'item', + '#title' => t('Code'), + '#value' => !empty($field['allowed_values_php']) ? '<code>'. check_plain($field['allowed_values_php']) .'</code>' : t('<none>'), + '#description' => empty($field['allowed_values_php']) ? t("You're not allowed to input PHP code.") : t('This PHP code was set by an administrator and will override the allowed values list above.'), + ); + } + return $form; + + case 'save': + return array('text_processing', 'max_length', 'allowed_values', 'allowed_values_php'); + + case 'database columns': + if (empty($field['max_length']) || $field['max_length'] > 255) { + $columns['value'] = array('type' => 'text', 'size' => 'big', 'not null' => FALSE, 'sortable' => TRUE, 'views' => TRUE); + } + else { + $columns['value'] = array('type' => 'varchar', 'length' => $field['max_length'], 'not null' => FALSE, 'sortable' => TRUE, 'views' => TRUE); + } + if (!empty($field['text_processing'])) { + $columns['format'] = array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'views' => FALSE); + } + return $columns; + + case 'views data': + $allowed_values = content_allowed_values($field); + if (count($allowed_values)) { + $data = content_views_field_views_data($field); + $db_info = content_database_info($field); + $table_alias = content_views_tablename($field); + + // Filter: Add a 'many to one' filter. + $copy = $data[$table_alias][$field['field_name'] .'_value']; + $copy['title'] = t('@label (!name) - Allowed values', array('@label' => t($field['widget']['label']), '!name' => $field['field_name'])); + $copy['filter']['handler'] = 'content_handler_filter_many_to_one'; + unset($copy['field'], $copy['argument'], $copy['sort']); + $data[$table_alias][$field['field_name'] .'_value_many_to_one'] = $copy; + // Argument : swap the handler to the 'many to one' operator. + $data[$table_alias][$field['field_name'] .'_value']['argument']['handler'] = 'content_handler_argument_many_to_one'; + return $data; + } + } +} + +/** + * Implementation of hook_field(). + */ +function text_field($op, &$node, $field, &$items, $teaser, $page) { + switch ($op) { + case 'validate': + $allowed_values = content_allowed_values($field); + if (is_array($items)) { + foreach ($items as $delta => $item) { + $error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; + if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); + if (!empty($item['value'])) { + if (count($allowed_values) && !array_key_exists($item['value'], $allowed_values)) { + form_set_error($error_element, t('%name: illegal value.', array('%name' => t($field['widget']['label'])))); + } + if (!empty($field['max_length']) && drupal_strlen($item['value']) > $field['max_length']) { + form_set_error($error_element, t('%name: the value may not be longer than %max characters.', array('%name' => $field['widget']['label'], '%max' => $field['max_length']))); + } + } + } + } + return $items; + + case 'sanitize': + foreach ($items as $delta => $item) { + if (!empty($field['text_processing'])) { + $text = isset($item['value']) ? check_markup($item['value'], $item['format'], FALSE) : ''; + } + else { + $text = isset($item['value']) ? check_plain($item['value']) : ''; + } + $items[$delta]['safe'] = $text; + } + } +} + +/** + * Implementation of hook_content_is_empty(). + */ +function text_content_is_empty($item, $field) { + if (empty($item['value']) && (string)$item['value'] !== '0') { + return TRUE; + } + return FALSE; +} + +/** + * Implementation of hook_field_formatter_info(). + */ +function text_field_formatter_info() { + return array( + 'default' => array( + 'label' => t('Default'), + 'field types' => array('text'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + 'plain' => array( + 'label' => t('Plain text'), + 'field types' => array('text'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + 'trimmed' => array( + 'label' => t('Trimmed'), + 'field types' => array('text'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + ); +} + +/** + * Theme function for 'default' text field formatter. + */ +function theme_text_formatter_default($element) { + return ($allowed =_text_allowed_values($element)) ? $allowed : $element['#item']['safe']; +} + +/** + * Theme function for 'plain' text field formatter. + */ +function theme_text_formatter_plain($element) { + return ($allowed =_text_allowed_values($element)) ? $allowed : strip_tags($element['#item']['safe']); +} + +/** + * Theme function for 'trimmed' text field formatter. + */ +function theme_text_formatter_trimmed($element) { + $field = content_fields($element['#field_name'], $element['#type_name']); + return ($allowed =_text_allowed_values($element)) ? $allowed : node_teaser($element['#item']['safe'], $field['text_processing'] ? $element['#item']['format'] : NULL); +} + +function _text_allowed_values($element) { + $field = content_fields($element['#field_name'], $element['#type_name']); + if (($allowed_values = content_allowed_values($field)) && isset($allowed_values[$element['#item']['value']])) { + return $allowed_values[$element['#item']['value']]; + } +} + +/** + * Implementation of hook_widget_info(). + * + * Here we indicate that the content module will handle + * the default value and multiple values for these widgets. + * + * Callbacks can be omitted if default handing is used. + * They're included here just so this module can be used + * as an example for custom modules that might do things + * differently. + */ +function text_widget_info() { + return array( + 'text_textfield' => array( + 'label' => t('Text field'), + 'field types' => array('text'), + 'multiple values' => CONTENT_HANDLE_CORE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + 'text_textarea' => array( + 'label' => t('Text area (multiple rows)'), + 'field types' => array('text'), + 'multiple values' => CONTENT_HANDLE_CORE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + ); +} + +/** + * Implementation of FAPI hook_elements(). + * + * Any FAPI callbacks needed for individual widgets can be declared here, + * and the element will be passed to those callbacks for processing. + * + * Drupal will automatically theme the element using a theme with + * the same name as the hook_elements key. + * + * Autocomplete_path is not used by text_widget but other widgets can use it + * (see nodereference and userreference). + */ +function text_elements() { + return array( + 'text_textfield' => array( + '#input' => TRUE, + '#columns' => array('value'), '#delta' => 0, + '#process' => array('text_textfield_process'), + '#autocomplete_path' => FALSE, + ), + 'text_textarea' => array( + '#input' => TRUE, + '#columns' => array('value', 'format'), '#delta' => 0, + '#process' => array('text_textarea_process'), + '#filter_value' => FILTER_FORMAT_DEFAULT, + ), + ); +} + +/** + * Implementation of hook_widget_settings(). + */ +function text_widget_settings($op, $widget) { + switch ($op) { + case 'form': + $form = array(); + $rows = (isset($widget['rows']) && is_numeric($widget['rows'])) ? $widget['rows'] : 5; + $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; + if ($widget['type'] == 'text_textfield') { + $form['rows'] = array('#type' => 'hidden', '#value' => $rows); + $form['size'] = array( + '#type' => 'textfield', + '#title' => t('Size of textfield'), + '#default_value' => $size, + '#element_validate' => array('_element_validate_integer_positive'), + '#required' => TRUE, + ); + } + else { + $form['rows'] = array( + '#type' => 'textfield', + '#title' => t('Rows'), + '#default_value' => $rows, + '#element_validate' => array('_element_validate_integer_positive'), + '#required' => TRUE, + ); + $form['size'] = array('#type' => 'hidden', '#value' => $size); + } + return $form; + + case 'save': + return array('rows', 'size'); + } +} + +/** + * Implementation of hook_widget(). + * + * Attach a single form element to the form. It will be built out and + * validated in the callback(s) listed in hook_elements. We build it + * out in the callbacks rather than here in hook_widget so it can be + * plugged into any module that can provide it with valid + * $field information. + * + * Content module will set the weight, field name and delta values + * for each form element. This is a change from earlier CCK versions + * where the widget managed its own multiple values. + * + * If there are multiple values for this field, the content module will + * call this function as many times as needed. + * + * @param $form + * the entire form array, $form['#node'] holds node information + * @param $form_state + * the form_state, $form_state['values'][$field['field_name']] + * holds the field's form values. + * @param $field + * the field array + * @param $items + * array of default values for this field + * @param $delta + * the order of this item in the array of subelements (0, 1, 2, etc) + * + * @return + * the form item for a single element for this field + */ +function text_widget(&$form, &$form_state, $field, $items, $delta = 0) { + $element = array( + '#type' => $field['widget']['type'], + '#default_value' => isset($items[$delta]) ? $items[$delta] : '', + ); + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function text_textfield_process($element, $edit, $form_state, $form) { + $field = $form['#field_info'][$element['#field_name']]; + $field_key = $element['#columns'][0]; + $delta = $element['#delta']; + $element[$field_key] = array( + '#type' => 'textfield', + '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, + '#autocomplete_path' => $element['#autocomplete_path'], + '#size' => !empty($field['widget']['size']) ? $field['widget']['size'] : 60, + '#attributes' => array('class' => 'text'), + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#description' => $element['#description'], + '#required' => $element['#required'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + + $element[$field_key]['#maxlength'] = !empty($field['max_length']) ? $field['max_length'] : NULL; + + if (!empty($field['text_processing'])) { + $filter_key = $element['#columns'][1]; + $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : FILTER_FORMAT_DEFAULT; + $parents = array_merge($element['#parents'] , array($filter_key)); + $element[$filter_key] = filter_form($format, 1, $parents); + } + + // Used so that hook_field('validate') knows where to flag an error. + $element['_error_element'] = array( + '#type' => 'value', + '#value' => implode('][', array_merge($element['#parents'], array($field_key))), + ); + + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function text_textarea_process($element, $edit, $form_state, $form) { + $field = $form['#field_info'][$element['#field_name']]; + $field_key = $element['#columns'][0]; + $element[$field_key] = array( + '#type' => 'textarea', + '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, + '#rows' => !empty($field['widget']['rows']) ? $field['widget']['rows'] : 10, + '#weight' => 0, + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#description' => $element['#description'], + '#required' => $element['#required'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + + if (!empty($field['text_processing'])) { + $filter_key = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format'; + $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : FILTER_FORMAT_DEFAULT; + $parents = array_merge($element['#parents'] , array($filter_key)); + $element[$filter_key] = filter_form($format, 1, $parents); + } + + // Used so that hook_field('validate') knows where to flag an error. + $element['_error_element'] = array( + '#type' => 'value', + '#value' => implode('][', array_merge($element['#parents'], array($field_key))), + ); + + return $element; +} + +/** + * FAPI theme for an individual text elements. + * + * The textfield or textarea is already rendered by the + * textfield or textarea themes and the html output + * lives in $element['#children']. Override this theme to + * make custom changes to the output. + * + * $element['#field_name'] contains the field name + * $element['#delta] is the position of this element in the group + */ +function theme_text_textfield($element) { + return $element['#children']; +} + +function theme_text_textarea($element) { + return $element['#children']; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.de.po new file mode 100644 index 0000000000000000000000000000000000000000..6f71b7fda0709d32380824b48c99b9fe741c8d4e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.de.po @@ -0,0 +1,74 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:10+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/text/text.module:42 +msgid "Store text in the database." +msgstr "Text in der Datenbank speichern." + +#: modules/text/text.module:55 +msgid "Filtered text (user selects input format)" +msgstr "Gefilterter Text (Benutzer wählt Eingabeformat aus)" + +#: modules/text/text.module:58 +msgid "Text processing" +msgstr "Textverarbeitung" + +#: modules/text/text.module:64 +msgid "Maximum length" +msgstr "Maximallänge" + +#: modules/text/text.module:68 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "Die maximale Zeichenlänge des Feldes. Für eine unbegrenzte Länge freilassen." + +#: modules/text/text.module:160 +msgid "%name: the value may not be longer than %max characters." +msgstr "%name: Der Wert darf nicht länger als %max Zeichen sein." + +#: modules/text/text.module:207 +msgid "Trimmed" +msgstr "Getrimmt" + +#: modules/text/text.module:265 +msgid "Text area (multiple rows)" +msgstr "Textfeld (mehrere Zeilen)" + +#: modules/text/text.module:326 +msgid "Rows" +msgstr "Zeilen" + +#: modules/text/text.module:0 +msgid "text" +msgstr "Text" + +#: modules/text/text.info:0 +msgid "Defines simple text field types." +msgstr "Definiert einfache Typen von Textfeldern." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..29e611c6d4a344b6b63d2fab9e922ea80f27c979 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.fr.po @@ -0,0 +1,33 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 13:24+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: modules/text/text.module:50 +msgid "Store text in the database." +msgstr "Enregistre le texte dans la base de données." + +#: modules/text/text.module:272 +msgid "Text area (multiple rows)" +msgstr "Zone de texte (plusieurs lignes)" + +#: modules/text/text.module:0 +msgid "text" +msgstr "texte" + +#: modules/text/text.info:0 +msgid "Defines simple text field types." +msgstr "Définit les types de champs en texte simple." diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..5e748933efb98e652b49b0b37cb76ff54f510d3a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.hu.po @@ -0,0 +1,156 @@ +# Hungarian translation of text (all releases) +# Copyright (c) 2008 by the Hungarian translation team +# Generated from files: +# text.module,v 1.95.2.20 2008/10/01 17:04:31 karens +# text.info,v 1.9 2008/04/23 18:02:31 dww +# +msgid "" +msgstr "" +"Project-Id-Version: text (all releases)\n" +"POT-Creation-Date: 2008-10-26 11:32-0500\n" +"PO-Revision-Date: 2008-10-26 09:41-0500\n" +"Last-Translator: Fehér János <feher.janos _at- mindworks.hu>\n" +"Language-Team: Drupal.hu Fordítói Csapat <forditas [at] drupal.hu>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: text.module:103,112 +msgid "Code" +msgstr "Kód" + +#: text.module:202 +msgid "Default" +msgstr "Alapértelmezett" + +#: text.module:66,207 +msgid "Plain text" +msgstr "Egyszerű szöveg" + +#: text.info:0 +msgid "CCK" +msgstr "CCK" + +#: text.module:96 +msgid "PHP code" +msgstr "PHP kód" + +#: text.module:113 +msgid "<none>" +msgstr "<nincs>" + +#: text.module:114 +msgid "You're not allowed to input PHP code." +msgstr "Nem engedélyezett a PHP kód bevitele." + +#: text.module:82 +msgid "Allowed values" +msgstr "Megengedett értékek" + +#: text.module:88 +msgid "Allowed values list" +msgstr "Megengedett értékek" + +#: text.module:92 +msgid "" +"The possible values this field can contain. Enter one value per line, " +"in the format key|label. The key is the value that will be stored in " +"the database, and it must match the field storage type (%type). The " +"label is optional, and the key will be used as the label if no label " +"is specified.<br />Allowed HTML tags: @tags" +msgstr "" +"A mező lehetséges értékei. Egy sorban egy értéket lehet megadni " +"kulcs|címke formában. A kulcs értéke kerül az adatbázisba, és " +"ennek meg kell felelnie az adatbázisban tárolt típussal (%type). A " +"címke nem kötelező, ha nincs megadva, akkor a kulcs kerül " +"felhasználásra, mint címke.<br />Engedélyezett HTML elemek: @tags" + +#: text.module:106 +msgid "" +"Advanced usage only: PHP code that returns a keyed array of allowed " +"values. Should not include <?php ?> delimiters. If this field is " +"filled out, the array returned by this code will override the allowed " +"values list above." +msgstr "" +"Csak haladóknak: PHP kód, ami visszaadja a megengedett értékek " +"tömbjét. Nem szükséges <?php ?> elemek közé zárni. Ha ez " +"a mező ki van töltve, a kód által visszaadott tömb felülír " +"minden fentebb megadott értéket." + +#: text.module:114 +msgid "" +"This PHP code was set by an administrator and will override the " +"allowed values list above." +msgstr "" +"Ezt a PHP kódot egy adminisztrátor állította be, és felül fogja " +"írni a fentebb megadott elfogadható értékek listáját." + +#: text.module:162 +msgid "%name: illegal value." +msgstr "%name: érvénytelen érték." + +#: text.module:262 +msgid "Text field" +msgstr "Szöveg mező" + +#: text.module:50 +msgid "Store text in the database." +msgstr "Szöveget tárol az adatbázisban." + +#: text.module:66 +msgid "Filtered text (user selects input format)" +msgstr "Formázott szöveg (a felhasználó választja ki a beviteli formát)" + +#: text.module:69 +msgid "Text processing" +msgstr "Szövegfeldolgozás" + +#: text.module:75 +msgid "Maximum length" +msgstr "Maximális hossz" + +#: text.module:78 +msgid "" +"The maximum length of the field in characters. Leave blank for an " +"unlimited size." +msgstr "" +"A mező karakterben mért maximális hossza. Üresen hagyva nincs " +"korlátozva." + +#: text.module:165 +msgid "%name: the value may not be longer than %max characters." +msgstr "%name: az érték nem lehet hosszabb %max karakternél." + +#: text.module:212 +msgid "Trimmed" +msgstr "Levágva" + +#: text.module:270 +msgid "Text area (multiple rows)" +msgstr "Szövegdoboz (többsoros)" + +#: text.module:322 +msgid "Size of textfield" +msgstr "A szövegmező mérete" + +#: text.module:331 +msgid "Rows" +msgstr "Sorok" + +#: text.module:348 +msgid "\"Rows\" must be a positive integer." +msgstr "A „Sorok” számának pozitív egész számot lehet megadni." + +#: text.module:355 +msgid "\"Size\" must be a positive integer." +msgstr "A méret csak pozitív egész szám lehet." + +#: text.module:0 +msgid "text" +msgstr "szöveg" + +#: text.module:49; text.info:0 +msgid "Text" +msgstr "Szöveg" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.nl.po new file mode 100644 index 0000000000000000000000000000000000000000..670ce8348a090666c4a96722f84e41849b2f65fb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.nl.po @@ -0,0 +1,147 @@ +# $Id$ +# +# Dutch translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# text.module,v 1.95.2.28 2008/12/30 00:00:54 yched +# text.info,v 1.9 2008/04/23 18:02:31 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-03 14:26+0200\n" +"PO-Revision-Date: 2009-06-03 14:26+0200\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: Dutch <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: text.module:41 text.info:0 +msgid "Text" +msgstr "Tekst" + +#: text.module:42 +msgid "Store text in the database." +msgstr "Bewaar tekst in de database." + +#: text.module:54;201 +msgid "Plain text" +msgstr "Platte tekst" + +#: text.module:54 +msgid "Filtered text (user selects input format)" +msgstr "Gefilterede tekst (gebruiker geeft invoerformaat op)" + +#: text.module:57 +msgid "Text processing" +msgstr "Tekstverwerking" + +#: text.module:63 +msgid "Maximum length" +msgstr "Maximum lengte" + +#: text.module:67 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "" +"De maximum lengte van het veld in karakters. Laat leeg voor " +"ongelimiteerde grootte." + +#: text.module:71 +msgid "Allowed values" +msgstr "Toegestane waardes" + +#: text.module:77 +msgid "Allowed values list" +msgstr "Lijst met toegestane waardes" + +#: text.module:81 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "" +"De mogelijke waardes die in dit veld kunnen staan. Voer één waarde " +"per regel in, in het formaat sleutel|label. De sleutel wordt in de " +"database opgeslagen en moet overeen komen met het veldopslagtype " +"(%type). Het label is optioneel. Als geen label wordt ingevoerd zal de " +"sleutel ook worden gebruikt als label. <br />Toegestane HTML-tags: " +"@tags" + +#: text.module:85 +msgid "PHP code" +msgstr "PHP code" + +#: text.module:92;101 +msgid "Code" +msgstr "Code" + +#: text.module:95 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "" +"Alleen voor geavanceerd gebruik: PHP-code die een array met sleutels " +"geeft van de toegestane waardes. Moet niet beginnen en eindigen met " +"<?php ?>. Als dit veld in ingevuld zullen de bovenstaande " +"toegestane waardes worden genegeerd." + +#: text.module:102 +msgid "<none>" +msgstr "<geen>" + +#: text.module:103 +msgid "You're not allowed to input PHP code." +msgstr "Je mag geen PHP-code gebruiken." + +#: text.module:103 +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "" +"Deze PHP-code is door een beheerder ingesteld en zal worden uitgevoerd " +"in plaats van de toegestane waardeslijst hierboven." + +#: text.module:132 +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Toegestane waardes" + +#: text.module:156 +msgid "%name: illegal value." +msgstr "%name: niet toegestane waarde." + +#: text.module:159 +msgid "%name: the value may not be longer than %max characters." +msgstr "%name: de waarde mag niet langer zijn dan %max karakters." + +#: text.module:196 +msgid "Default" +msgstr "Standaard" + +#: text.module:206 +msgid "Trimmed" +msgstr "Ingekort" + +#: text.module:256 +msgid "Text field" +msgstr "Tekstveld" + +#: text.module:264 +msgid "Text area (multiple rows)" +msgstr "Tekstveld (meerdere rijen)" + +#: text.module:316 +msgid "Size of textfield" +msgstr "Maat van het tekstveld" + +#: text.module:325 +msgid "Rows" +msgstr "Rijen" + +#: text.module:0 +msgid "text" +msgstr "tekst" + +#: text.info:0 +msgid "Defines simple text field types." +msgstr "Levert simpele tekstveldtypes." + +#: text.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.pot new file mode 100644 index 0000000000000000000000000000000000000000..0313ebd39ad3ba4547487cc8a9d5520cf01cc007 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.pot @@ -0,0 +1,65 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-text) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# text.module,v 1.95.2.29 2009/04/29 20:51:53 karens +# text.info,v 1.9 2008/04/23 18:02:31 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/text/text.module:42 +msgid "Store text in the database." +msgstr "" + +#: modules/text/text.module:55 +msgid "Filtered text (user selects input format)" +msgstr "" + +#: modules/text/text.module:58 +msgid "Text processing" +msgstr "" + +#: modules/text/text.module:64 +msgid "Maximum length" +msgstr "" + +#: modules/text/text.module:68 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "" + +#: modules/text/text.module:160 +msgid "%name: the value may not be longer than %max characters." +msgstr "" + +#: modules/text/text.module:207 +msgid "Trimmed" +msgstr "" + +#: modules/text/text.module:265 +msgid "Text area (multiple rows)" +msgstr "" + +#: modules/text/text.module:326 +msgid "Rows" +msgstr "" + +#: modules/text/text.module:0 +msgid "text" +msgstr "" + +#: modules/text/text.info:0 +msgid "Defines simple text field types." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..54756ea98b9feb88303c3750bcc8ea354d82f2b5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.sv.po @@ -0,0 +1,135 @@ +# $Id$ +# +# Swedish translation of Drupal (text) +# Generated from files: +# text.module,v 1.95.2.29 2009/04/29 20:51:53 karens +# text.info,v 1.9 2008/04/23 18:02:31 dww +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Text 6.x\n" +"POT-Creation-Date: 2009-05-27 13:47+0200\n" +"PO-Revision-Date: 2009-05-27 14:27+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: text.module:41 +#: text.info:0 +msgid "Text" +msgstr "Text" + +#: text.module:42 +msgid "Store text in the database." +msgstr "Lagra text i databasen." + +#: text.module:55;202 +msgid "Plain text" +msgstr "Ren text" + +#: text.module:55 +msgid "Filtered text (user selects input format)" +msgstr "Filtrerade text (användare väljer inmatningsformat)" + +#: text.module:58 +msgid "Text processing" +msgstr "Bearbetning av text" + +#: text.module:64 +msgid "Maximum length" +msgstr "Maximal längd" + +#: text.module:68 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "Maximalt antal tecken för fältet. Lämna blankt för oändlig storlek." + +#: text.module:72 +msgid "Allowed values" +msgstr "Tillåtna värden" + +#: text.module:78 +msgid "Allowed values list" +msgstr "Tillåtna listvärden" + +#: text.module:82 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "De möjliga värdena detta fält kan innehålla. Ange ett värde per rad i formatet nyckel/etikett. Denna nyckel är värdet som kommer att lagras i databasen och måste överensstämma typen för fältlagring (%type). Etikett är valfritt, och nyckeln som kommer att användas är etiketten om ingen etikett är specificerad.<br />Tillåtna HTML-taggar: @tags" + +#: text.module:86 +msgid "PHP code" +msgstr "PHP-kod" + +#: text.module:93;102 +msgid "Code" +msgstr "Kod" + +#: text.module:96 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Enbart avancerat användande: PHP-kod som skall returnera en spärrad lista av tillåtna värden. Skall inte inkludera avgränsarna <?php ?>. Om detta fält är ifyllt kommer listan som returneras av denna kod att åsidosätta det tillåtna värdet i listan ovan." + +#: text.module:103 +msgid "<none>" +msgstr "<ingen>" + +#: text.module:104 +msgid "You're not allowed to input PHP code." +msgstr "Du har inte tillåtelse att mata in PHP-kod." + +#: text.module:104 +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "Denna PHP-kod angavs av en administratör och kommer att åsidosätta det tillåtna värdet ovan." + +#: text.module:133 +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Tillåtna värden" + +#: text.module:157 +msgid "%name: illegal value." +msgstr "%name: otillåtet värde." + +#: text.module:160 +msgid "%name: the value may not be longer than %max characters." +msgstr "%name: värdet får inte vara längre än %max tecken." + +#: text.module:197 +msgid "Default" +msgstr "Standard" + +#: text.module:207 +msgid "Trimmed" +msgstr "Avkortad" + +#: text.module:257 +msgid "Text field" +msgstr "Textfält" + +#: text.module:265 +msgid "Text area (multiple rows)" +msgstr "Textområde (flera rader)" + +#: text.module:317 +msgid "Size of textfield" +msgstr "Storlek på textfält" + +#: text.module:326 +msgid "Rows" +msgstr "Rader" + +#: text.module:0 +msgid "text" +msgstr "text" + +#: text.info:0 +msgid "Defines simple text field types." +msgstr "Definierar enkla typer av textfält." + +#: text.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..4b4cb95acfb2a34ec3a56f0d404163a29326135b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.help.ini @@ -0,0 +1,8 @@ +; $Id$ + +[advanced help settings] +hide = TRUE + +[userreference] +title = Userreference field +parent = content%fields diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.html new file mode 100644 index 0000000000000000000000000000000000000000..ef8125172c270af209f68a17095ca67781ad83b6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.html @@ -0,0 +1,3 @@ +<p>The Userreference field stores the uid of a related user. The name of the related user is usually displayed as the value of this field.</p> +<p>The Userreference field can use an autocomplete widget, or, when used with <a href="&topic:optionwidgets/optionwidgets&">Optionwidgets</a>, the available values can be presented to the end user in a drop-down select list, checkboxes, or radios.</p> +<p>A Userreference field can be used in Views to create a <a href="&topic:views/relationship&">Relationship</a> to a user, to allow you to use any field, argument, or filter from the related user in your view. </p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/panels/relationships/user_from_userref.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/panels/relationships/user_from_userref.inc new file mode 100644 index 0000000000000000000000000000000000000000..4af22ad2680e805307428ed777772aea30de5c11 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/panels/relationships/user_from_userref.inc @@ -0,0 +1,65 @@ +<?php +// $Id$ + +/** + * @file + * Implements the user reference relationship for Panels. + */ + +/** + * Implementation of hook_ctools_relationships(). + */ +function userreference_user_from_userref_ctools_relationships() { + return array( + 'title' => t('User from reference'), + 'keyword' => 'userreference', + 'description' => t('Adds a user from a user reference in a node context; if multiple users are referenced, this will get the first referenced user only.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'context' => 'userreference_user_from_userref_context', + 'settings form' => 'userreference_user_from_userref_settings_form', + 'settings form validate' => 'userreference_user_from_userref_settings_form_validate', + ); +} + +/** + * Return a new ctools context based on an existing context. + */ +function userreference_user_from_userref_context($context, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data)) { + return ctools_context_create_empty('user', NULL); + } + + // Prevent whitescreens on stale data. + if (empty($conf)) { + return ctools_context_create_empty('user', NULL); + } + + if (isset($context->data->{$conf['field_name']}[0]['uid']) && ($uid = $context->data->{$conf['field_name']}[0]['uid'])) { + if ($account = user_load(array('uid' => $uid))) { + return ctools_context_create('user', $account); + } + } +} + +/** + * Settings form for the ctools relationship. + */ +function userreference_user_from_userref_settings_form($conf) { + $options = array(); + foreach (content_fields() as $field) { + if ($field['type'] == 'userreference') { + $options[$field['field_name']] = t($field['widget']['label']); + } + } + $form['field_name'] = array( + '#title' => t('User reference field'), + '#type' => 'select', + '#options' => $options, + '#default_value' => isset($conf['field_name']) ? $conf['field_name'] : '', + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + + return $form; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.de.po new file mode 100644 index 0000000000000000000000000000000000000000..9e46e5d5b745c643030c8b8947aa2852e4aaafcb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.de.po @@ -0,0 +1,42 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:12+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/userreference/panels/relationships/user_from_userref.inc:14 +msgid "User from reference" +msgstr "Benutzer der Referenz" + +#: modules/userreference/panels/relationships/user_from_userref.inc:16 +msgid "Adds a user from a user reference in a node context; if multiple users are referenced, this will get the first referenced user only." +msgstr "" + +#: modules/userreference/panels/relationships/user_from_userref.inc:50 +msgid "User reference field" +msgstr "Benutzerreferenzfeld" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.pot new file mode 100644 index 0000000000000000000000000000000000000000..37a78d6f46620a8da4666d11f0706ab52ac42671 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.pot @@ -0,0 +1,31 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-userreference-panels-relationships) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from file: user_from_userref.inc,v 1.1.2.1 2009/06/02 12:24:04 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/userreference/panels/relationships/user_from_userref.inc:14 +msgid "User from reference" +msgstr "" + +#: modules/userreference/panels/relationships/user_from_userref.inc:16 +msgid "Adds a user from a user reference in a node context; if multiple users are referenced, this will get the first referenced user only." +msgstr "" + +#: modules/userreference/panels/relationships/user_from_userref.inc:50 +msgid "User reference field" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.de.po new file mode 100644 index 0000000000000000000000000000000000000000..3d7837ab13822c403004f3cdc83a44304f60c5cd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.de.po @@ -0,0 +1,136 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-03-09 23:01+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: modules/userreference/userreference.rules.inc:15 +msgid "Load a referenced user" +msgstr "Einen referenzierten Benutzer laden" + +#: modules/userreference/userreference.rules.inc:19 +msgid "Content containing the user reference field" +msgstr "Der Inhalt der das Benutzerreferenzfeld enthält" + +#: modules/userreference/userreference.rules.inc:25 +msgid "Referenced user" +msgstr "Referenzierter Benutzer" + +#: modules/userreference/userreference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first user will be loaded." +msgstr "Sollte ein Feld mehrere Werte enthalten, wird nur der erste Benutzer geladen." + +#: modules/userreference/userreference.rules.inc:52 +msgid "There are no userreference fields defined." +msgstr "Es sind keine Benutzerreferenzfelder vorhanden." + +#: modules/userreference/userreference.module:52 +msgid "User reference" +msgstr "Benutzerreferenz" + +#: modules/userreference/userreference.module:53 +msgid "Store the ID of a related user as an integer value." +msgstr "Speichert die ID eines zugehörigen Benutzers als ganzzahligen Wert." + +#: modules/userreference/userreference.module:67 +msgid "User roles that can be referenced" +msgstr "Benutzerrollen auf die referenziert werden kann" + +#: modules/userreference/userreference.module:73 +msgid "User status that can be referenced" +msgstr "Benutzerstatus der referenziert werden kann" + +#: modules/userreference/userreference.module:75 +msgid "Active" +msgstr "Aktiv" + +#: modules/userreference/userreference.module:75 +msgid "Blocked" +msgstr "Gesperrt" + +#: modules/userreference/userreference.module:94 +msgid "Advanced - Users that can be referenced (View)" +msgstr "Erweitert - Benutzer die referenziert werden können (Ansicht)" + +#: modules/userreference/userreference.module:101 +msgid "View used to select the users" +msgstr "Die zur Auswahl von Benutzern verwendete Ansicht" + +#: modules/userreference/userreference.module:104 +#, fuzzy +msgid "<p>Choose the \"Views module\" view that selects the users that can be referenced.<br />Note:</p>" +msgstr "<p>Wähle die „Views-Modul“-Ansicht das die Beiträge auswählt, die Referenziert werden können.<br />Hinweis:</p>" + +#: modules/userreference/userreference.module:105;118 +#, fuzzy +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.</li></ul>" +msgstr "<ul><li>Nur Ansichten mit Feldern werden für diesen Zweck nutzbar sein.</li><li>Dies wird die obigen Einstellungen der „referenzierbaren Rollen“ und „referenzierbaren Status“ verwerfen. Stattdessen sollte hierfür der „Filter“-Bereich der Ansicht verwendet werden.</li><li>Um weitere Informationen über Beitragskandidaten für das Erstellungs-/Bearbeitungsformular anzuzeigen, kann das Ansichten-Feld verwendet werden.</li><li>Um die Reihenfolge der Beitragskandidaten festzulegen sollte das „Sortierkriterium“ von Ansichten verwendet werden.</li></ul>" + +#: modules/userreference/userreference.module:117 +msgid "<p>The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +#: modules/userreference/userreference.module:196 +msgid "%name: invalid user." +msgstr "%name: Der Benutzer ist ungültig." + +#: modules/userreference/userreference.module:349 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users." +msgstr "Die Methode zur Sammlung von Autovervollständigungsvorschlägen auswählen. Dabei ist zu beachten, dass <em>Enthält</em> auf Websites mit tausenden von Benutzern große Performanceprobleme verursachen kann." + +#: modules/userreference/userreference.module:357 +msgid "Reverse link" +msgstr "‚Zurück‘-Link" + +#: modules/userreference/userreference.module:359 +msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record." +msgstr "Sobald ausgewählt, wird auf dem referenzierten Benutzerdatensatz ein ‚Zurück‘-Link zu dem referenzierten Beitrag angezeigt." + +#: modules/userreference/userreference.module:594 +msgid "%name: found no valid user with that name." +msgstr "%name: Kein Benutzer mit diesem Namen gefunden." + +#: modules/userreference/userreference.module:889 +msgid "Related content" +msgstr "Zugehöriger Inhalt" + +#: modules/userreference/userreference.module:15 +msgid "Userreference autocomplete" +msgstr "Autovervollständigung der Benutzerreferenzen" + +#: modules/userreference/userreference.module:0 +msgid "userreference" +msgstr "Benutzerreferenz" + +#: modules/userreference/userreference.info:0 +msgid "User Reference" +msgstr "Benutzerreferenz" + +#: modules/userreference/userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "Definiert einen Feldtyp mit dem von einem Beitrag auf einen Benutzer verwiesen werden kann." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..3a9c8e6d81dce6824be47f7f1822578c9449d9aa --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.fr.po @@ -0,0 +1,89 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 13:24+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: modules/userreference/userreference.module:52 +msgid "User reference" +msgstr "Référence utilisateur" + +#: modules/userreference/userreference.module:53 +msgid "Store the ID of a related user as an integer value." +msgstr "" +"Enregistre l'identifiant d'un utilisateur associé, sous la forme d'une " +"valeur entière." + +#: modules/userreference/userreference.module:71 +msgid "User roles that can be referenced" +msgstr "Rôles utilisateur pouvant être référencés" + +#: modules/userreference/userreference.module:77 +msgid "User status that can be referenced" +msgstr "Statuts utilisateur pouvant être référencés" + +#: modules/userreference/userreference.module:79 +msgid "Active" +msgstr "Actif" + +#: modules/userreference/userreference.module:79 +msgid "Blocked" +msgstr "Bloqué" + +#: modules/userreference/userreference.module:122 +msgid "%name: Invalid user." +msgstr "Champ '%name' : utilisateur invalide." + +#: modules/userreference/userreference.module:253 +msgid "Reverse link" +msgstr "Lien réciproque" + +#: modules/userreference/userreference.module:255 +msgid "No" +msgstr "Non" + +#: modules/userreference/userreference.module:255 +msgid "Yes" +msgstr "Oui" + +#: modules/userreference/userreference.module:257 +msgid "" +"If selected, a reverse link back to the referencing node will displayed on " +"the referenced user record." +msgstr "" +"Si cette option est sélectionnée, un lien réciproque vers le nœud " +"référençant sera affiché dans l'enregistrement utilisateur référencé." + +#: modules/userreference/userreference.module:586 +msgid "Related content" +msgstr "Contenus liés" + +#: modules/userreference/userreference.module:15 +msgid "Userreference autocomplete" +msgstr "Autocomplètement de la référence utilisateur" + +#: modules/userreference/userreference.module:0 +msgid "userreference" +msgstr "userreference" + +#: modules/userreference/userreference.info:0 +msgid "User Reference" +msgstr "User Reference" + +#: modules/userreference/userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "" +"Définit un type de champ qui permet d'établir des liens entre les nœuds et " +"les utilisateurs." diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..1e1c86dcc724c80dae5b59f250396a3ca00b0d2c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.hu.po @@ -0,0 +1,137 @@ +# Hungarian translation of cck (6.x-2.0-rc10) +# Copyright (c) 2008 by the Hungarian translation team +# Generated from files: +# userreference.module,v 1.106.2.21 2008/10/07 10:17:51 karens +# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# userreference.info,v 1.8 2008/04/23 18:02:38 dww +# +msgid "" +msgstr "" +"Project-Id-Version: cck (6.x-2.0-rc10)\n" +"POT-Creation-Date: 2008-10-31 12:16-0500\n" +"PO-Revision-Date: 2008-10-26 16:42-0500\n" +"Last-Translator: Balogh Zoltán\n" +"Language-Team: Drupal.hu Fordítói Csapat <forditas [at] drupal.hu>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: modules/userreference/userreference.module:97 +msgid "Active" +msgstr "Aktív" + +#: modules/userreference/userreference.module:97 +msgid "Blocked" +msgstr "Blokkolt" + +#: modules/userreference/userreference.rules.inc:15 +msgid "Load a referenced user" +msgstr "Egy hivatkozott felhasználó betöltése" + +#: modules/userreference/userreference.rules.inc:19 +msgid "Content containing the user reference field" +msgstr "A felhasználóhivatkozás mező tartalma" + +#: modules/userreference/userreference.rules.inc:25 +msgid "Referenced user" +msgstr "Hivatkozott felhasználó" + +#: modules/userreference/userreference.rules.inc:29 +msgid "" +"Note that if the field has multiple values, only the first user will " +"be loaded." +msgstr "" +"Megjegyzés: Ha a mezőnek több értéke is lehet, akkor csak az " +"első felhasználó lesz betöltve." + +#: modules/userreference/userreference.rules.inc:52 +msgid "There are no userreference fields defined." +msgstr "Nincsenek felhasználóhivatkozás mezők meghatározva." + +#: modules/userreference/userreference.module:70 +msgid "User reference" +msgstr "Hivatkozás felhasználóra" + +#: modules/userreference/userreference.module:71 +msgid "Store the ID of a related user as an integer value." +msgstr "" +"A hivatkozott felhasználó azonosítójának tárolása egész " +"számként." + +#: modules/userreference/userreference.module:89 +msgid "User roles that can be referenced" +msgstr "Felhasználói csoport, amelyre hivatkozni lehet" + +#: modules/userreference/userreference.module:95 +msgid "User status that can be referenced" +msgstr "Felhasználói állapot, amelyre hivatkozni lehet" + +#: modules/userreference/userreference.module:117 +msgid "Advanced - Users that can be referenced (View)" +msgstr "Haladó - Felhasználók, akikre hivatkozni lehet (Nézet)" + +#: modules/userreference/userreference.module:123 +msgid "View used to select the users" +msgstr "A felhasználók kiválasztásához használt nézet" + +#: modules/userreference/userreference.module:126 +msgid "" +"Choose the \"Views module\" view that selects the users that can be " +"referenced.<br />Note:<ul><li>Only views that have fields will work " +"for this purpose.</li><li>This will discard the \"Referenceable " +"Roles\" and \"Referenceable Status\" settings above. Use the view's " +"\"filters\" section instead.</li><li>Use the view's \"fields\" section " +"to display additional informations about candidate users on user " +"creation/edition form.</li><li>Use the view's \"sort criteria\" " +"section to determine the order in which candidate users will be " +"displayed.</li></ul>" +msgstr "" +"A „Nézet modul” egyik nézetének kiválasztása, mely azokat a " +"felhasználókat mutatja, akikre hivatkozni " +"lehet.<br>Megjegyzés:<ul><li>Itt csak olyan nézet működik, melynek " +"vannak mezői.</li><li>Ez felülírja a fenti „Hivatkozható " +"csoportok” és „Hivatkozható állapotok” beállításokat. A " +"nézet „szűrő” feltétele használható e helyett.</li><li>A " +"nézet „mezők” része használható arra, hogy bővebb " +"információkat jelenítsen meg a lehetséges felhasználókról a " +"szerkesztő űrlapon.</li><li>A nézet „sorrend” része " +"befolyásolja a lehetséges felhasználók megjelenítési " +"sorrendjét.</li></ul>" + +#: modules/userreference/userreference.module:185 +msgid "%name: invalid user." +msgstr "%name: érvénytelen felhasználó." + +#: modules/userreference/userreference.module:329 +msgid "Reverse link" +msgstr "Visszamutató hivatkozás" + +#: modules/userreference/userreference.module:331 +msgid "" +"If selected, a reverse link back to the referencing node will " +"displayed on the referenced user record." +msgstr "" +"Ha be van jelölve, akkor a felhasználó adatlapján egy hivatkozás " +"visszamutat a hivatkozó tartalomra." + +#: modules/userreference/userreference.module:830 +msgid "Related content" +msgstr "Kapcsolódó tartalom" + +#: modules/userreference/userreference.module:15 +msgid "Userreference autocomplete" +msgstr "Felhasználóhivatkozás automatikus kiegészítéssel" + +#: modules/userreference/userreference.module:0 +msgid "userreference" +msgstr "felhasználóhivatkozás" + +#: modules/userreference/userreference.info:0 +msgid "User Reference" +msgstr "Felhasználói hivatkozás" + +#: modules/userreference/userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "Olyan mezőtípus, amely a tartalomban egy felhasználóra hivatkozik." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.nl.po new file mode 100644 index 0000000000000000000000000000000000000000..efdea016f115fc511fd0a227ce25fa2569e24669 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.nl.po @@ -0,0 +1,209 @@ +# $Id$ +# +# Dutch translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# userreference.module,v 1.106.2.36 2009/03/18 21:00:58 yched +# userreference.info,v 1.8 2008/04/23 18:02:38 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-03 14:26+0200\n" +"PO-Revision-Date: 2009-06-03 14:26+0200\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: Dutch <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: userreference.rules.inc:15 +msgid "Load a referenced user" +msgstr "Laad een gerefereerde gebruiker" + +#: userreference.rules.inc:19 +msgid "Content containing the user reference field" +msgstr "Inhoud dat het gebruikersreferentieveld bevat" + +#: userreference.rules.inc:25 +msgid "Referenced user" +msgstr "Gerefereerde gebruiker" + +#: userreference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first user will be loaded." +msgstr "" +"Merk op dat als het veld meerdere waardes heeft, alleen de eerste " +"gebruiker zal worden geladen." + +#: userreference.rules.inc:47 +msgid "Field" +msgstr "Veld" + +#: userreference.rules.inc:52 +msgid "There are no userreference fields defined." +msgstr "Er zijn geen gebruikersreferentievelden ingesteld." + +#: userreference.module:52 +msgid "User reference" +msgstr "Gebruikersreferentie" + +#: userreference.module:53 +msgid "Store the ID of a related user as an integer value." +msgstr "Bewaar de ID van een gerelateerde gebruiker als een integer-waarde" + +#: userreference.module:67 +msgid "User roles that can be referenced" +msgstr "Gebruikersrollen die kunnen worden gerefereerd" + +#: userreference.module:73 +msgid "User status that can be referenced" +msgstr "Gebruikersstatus die kan worden gerefereerd" + +#: userreference.module:75 +msgid "Active" +msgstr "Actief" + +#: userreference.module:75 +msgid "Blocked" +msgstr "Geblokkeerd" + +#: userreference.module:84 +msgid "Default Views" +msgstr "Standaard views" + +#: userreference.module:87 +msgid "Existing Views" +msgstr "Bestaande Views" + +#: userreference.module:94 +msgid "Advanced - Users that can be referenced (View)" +msgstr "Geavanceerd - Gebruikers die kunnen worden gerefereerd (View)" + +#: userreference.module:101 +msgid "View used to select the users" +msgstr "View die gebruikt wordt om gebruikers te selecteren" + +#: userreference.module:104 +msgid "<p>Choose the \"Views module\" view that selects the users that can be referenced.<br />Note:</p>" +msgstr "" +"<p>Kies de \"Views module\"-view die de gebruikers selecteert die " +"kunnen worden gerefereerd.<br />Merk op:</p>" + +#: userreference.module:105;118 +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.</li></ul>" +msgstr "" +"<ul><li>Alleen Views met velden zullen werken voor dit " +"doel.</li><li>Dit zal de \"Refereerbare Rollen-\" en \"Refereerbare " +"Status\"-instellingen boven negeren. Gebruik anders de view z'n " +"\"filters\" sectie.</li><li>Gebruik de view z'n \"velden\"-sectie om " +"extra informatie over gebruikers op het bewerkformulier weer te " +"geven.</li><li>Gebruik de view z'n \"sorteercriteria\"-sectie om de " +"volgorde te bepalen waarin gebruikers worden weergegeven.</li></ul>" + +#: userreference.module:109 +msgid "View arguments" +msgstr "Bekijk argumenten" + +#: userreference.module:112 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "" +"Geef een door komma's gescheiden lijst met argumenten op om naar de " +"view te sturen." + +#: userreference.module:117 +msgid "<p>The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" +"<p>De lijst met gebruikers die kunnen worden gerefereerd op basis van " +"een \"Views module\"-view, maar geen passende views gevonden. <br " +"/>Merk op:</p>" + +#: userreference.module:184 +msgid "%name: invalid input." +msgstr "%name: geen toegestane waarde." + +#: userreference.module:196 +msgid "%name: invalid user." +msgstr "%name: geen toegestane gebruiker." + +#: userreference.module:221 +msgid "Default" +msgstr "Standaard" + +#: userreference.module:226 +msgid "Plain text" +msgstr "Platte tekst" + +#: userreference.module:273 +msgid "Select list" +msgstr "Selectielijst" + +#: userreference.module:281 +msgid "Check boxes/radio buttons" +msgstr "Vinkje/radio buttons" + +#: userreference.module:289 +msgid "Autocomplete text field" +msgstr "Automatisch aanvullend tekstveld" + +#: userreference.module:343 +msgid "Autocomplete matching" +msgstr "Automatisch aanvullende overeenkomst" + +#: userreference.module:346 +msgid "Starts with" +msgstr "Begint met" + +#: userreference.module:347 +msgid "Contains" +msgstr "Bevat" + +#: userreference.module:349 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users." +msgstr "" +"Selecteer de methode die wordt gebruikt om automatisch aangevulde " +"suggesties te geven. Merk op <em>Bevat</em> prestatieproblemen kan " +"veroorzaken op sites met vele duizenden gebruikers." + +#: userreference.module:357 +msgid "Reverse link" +msgstr "Link terug" + +#: userreference.module:359 +msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record." +msgstr "" +"Als geselecteerd zal een links terug worden geplaatst naar de " +"gerefereerde node in de gerefereerde gebruiker." + +#: userreference.module:594 +msgid "%name: found no valid user with that name." +msgstr "%name: geen toegestane gebruiker gevonden met die naam." + +#: userreference.module:887 +msgid "Related content" +msgstr "Gerelateerde inhoud" + +#: userreference.module:15 +msgid "Userreference autocomplete" +msgstr "Gebruikersreferentie automatische aanvulling" + +#: userreference.module:0 +msgid "userreference" +msgstr "gebruikersreferentie" + +#: userreference.info:0 +msgid "User Reference" +msgstr "Gebruikersreferentie" + +#: userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "" +"Levert een veldtype for het refereren van een gebruiker vanuit een " +"node." + +#: userreference.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.pot new file mode 100644 index 0000000000000000000000000000000000000000..38eaf2a2b47863a879a62cdb37fabd8d3723b2d5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.pot @@ -0,0 +1,126 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (modules-userreference) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# userreference.module,v 1.106.2.43 2009/06/02 12:24:04 yched +# userreference.info,v 1.8 2008/04/23 18:02:38 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: modules/userreference/userreference.rules.inc:15 +msgid "Load a referenced user" +msgstr "" + +#: modules/userreference/userreference.rules.inc:19 +msgid "Content containing the user reference field" +msgstr "" + +#: modules/userreference/userreference.rules.inc:25 +msgid "Referenced user" +msgstr "" + +#: modules/userreference/userreference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first user will be loaded." +msgstr "" + +#: modules/userreference/userreference.rules.inc:52 +msgid "There are no userreference fields defined." +msgstr "" + +#: modules/userreference/userreference.module:61 +msgid "User reference" +msgstr "" + +#: modules/userreference/userreference.module:62 +msgid "Store the ID of a related user as an integer value." +msgstr "" + +#: modules/userreference/userreference.module:77 +msgid "User roles that can be referenced" +msgstr "" + +#: modules/userreference/userreference.module:83 +msgid "User status that can be referenced" +msgstr "" + +#: modules/userreference/userreference.module:85 +msgid "Active" +msgstr "" + +#: modules/userreference/userreference.module:85 +msgid "Blocked" +msgstr "" + +#: modules/userreference/userreference.module:104 +msgid "Advanced - Users that can be referenced (View)" +msgstr "" + +#: modules/userreference/userreference.module:111 +msgid "View used to select the users" +msgstr "" + +#: modules/userreference/userreference.module:114 +msgid "<p>Choose the \"Views module\" view that selects the users that can be referenced.<br />Note:</p>" +msgstr "" + +#: modules/userreference/userreference.module:115;128 +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.</li></ul>" +msgstr "" + +#: modules/userreference/userreference.module:127 +msgid "<p>The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +#: modules/userreference/userreference.module:207 +msgid "%name: invalid user." +msgstr "" + +#: modules/userreference/userreference.module:361 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users." +msgstr "" + +#: modules/userreference/userreference.module:377 +msgid "Reverse link" +msgstr "" + +#: modules/userreference/userreference.module:379 +msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record." +msgstr "" + +#: modules/userreference/userreference.module:614 +msgid "%name: found no valid user with that name." +msgstr "" + +#: modules/userreference/userreference.module:908 +msgid "Related content" +msgstr "" + +#: modules/userreference/userreference.module:15 +msgid "Userreference autocomplete" +msgstr "" + +#: modules/userreference/userreference.module:0 +msgid "userreference" +msgstr "" + +#: modules/userreference/userreference.info:0 +msgid "User Reference" +msgstr "" + +#: modules/userreference/userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..cd3c5ca64a62fe81a19bb75d4b01dfb316af137e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.sv.po @@ -0,0 +1,191 @@ +# $Id$ +# +# Swedish translation of Drupal (userreference) +# Generated from files: +# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# userreference.module,v 1.106.2.42 2009/05/16 16:41:30 yched +# userreference.info,v 1.8 2008/04/23 18:02:38 dww +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Userreference\n" +"POT-Creation-Date: 2009-05-27 13:47+0200\n" +"PO-Revision-Date: 2009-05-27 13:48+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: userreference.rules.inc:15 +msgid "Load a referenced user" +msgstr "" + +#: userreference.rules.inc:19 +msgid "Content containing the user reference field" +msgstr "" + +#: userreference.rules.inc:25 +msgid "Referenced user" +msgstr "" + +#: userreference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first user will be loaded." +msgstr "" + +#: userreference.rules.inc:47 +msgid "Field" +msgstr "Fält" + +#: userreference.rules.inc:52 +msgid "There are no userreference fields defined." +msgstr "" + +#: userreference.module:52 +msgid "User reference" +msgstr "" + +#: userreference.module:53 +msgid "Store the ID of a related user as an integer value." +msgstr "" + +#: userreference.module:68 +msgid "User roles that can be referenced" +msgstr "" + +#: userreference.module:74 +msgid "User status that can be referenced" +msgstr "" + +#: userreference.module:76 +msgid "Active" +msgstr "Aktiv" + +#: userreference.module:76 +msgid "Blocked" +msgstr "Spärrad" + +#: userreference.module:85 +msgid "Default Views" +msgstr "Förvald vy" + +#: userreference.module:88 +msgid "Existing Views" +msgstr "Existerande vyer" + +#: userreference.module:95 +msgid "Advanced - Users that can be referenced (View)" +msgstr "" + +#: userreference.module:102 +msgid "View used to select the users" +msgstr "" + +#: userreference.module:105 +msgid "<p>Choose the \"Views module\" view that selects the users that can be referenced.<br />Note:</p>" +msgstr "" + +#: userreference.module:106;119 +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.</li></ul>" +msgstr "" + +#: userreference.module:110 +msgid "View arguments" +msgstr "Argument för vy" + +#: userreference.module:113 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Tillhandahåll en kommaseparerad lista av argument att skicka till vyn." + +#: userreference.module:118 +msgid "<p>The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +#: userreference.module:186 +msgid "%name: invalid input." +msgstr "%name: ogiltig inmatning." + +#: userreference.module:198 +msgid "%name: invalid user." +msgstr "" + +#: userreference.module:223 +msgid "Default" +msgstr "Standard" + +#: userreference.module:228 +msgid "Plain text" +msgstr "Ren text" + +#: userreference.module:275 +msgid "Select list" +msgstr "Listval" + +#: userreference.module:283 +msgid "Check boxes/radio buttons" +msgstr "Kryssrutor/radioknappar" + +#: userreference.module:291 +msgid "Autocomplete text field" +msgstr "Automatiskt kompletterande textfält" + +#: userreference.module:346 +msgid "Autocomplete matching" +msgstr "Automatiskt kompletterande som överensstämmer" + +#: userreference.module:349 +msgid "Starts with" +msgstr "Börjar med" + +#: userreference.module:350 +msgid "Contains" +msgstr "Innehåller" + +#: userreference.module:352 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users." +msgstr "" + +#: userreference.module:356 +msgid "Size of textfield" +msgstr "" + +#: userreference.module:368 +msgid "Reverse link" +msgstr "" + +#: userreference.module:370 +msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record." +msgstr "" + +#: userreference.module:605 +msgid "%name: found no valid user with that name." +msgstr "" + +#: userreference.module:899 +msgid "Related content" +msgstr "" + +#: userreference.module:15 +msgid "Userreference autocomplete" +msgstr "" + +#: userreference.module:0 +msgid "userreference" +msgstr "" + +#: userreference.info:0 +msgid "User Reference" +msgstr "" + +#: userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "" + +#: userreference.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.info new file mode 100644 index 0000000000000000000000000000000000000000..b128a00f0d4447d80df0e8c15935143377848efa --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.info @@ -0,0 +1,14 @@ +; $Id$ +name = User Reference +description = Defines a field type for referencing a user from a node. +dependencies[] = content +dependencies[] = text +dependencies[] = optionwidgets +package = CCK +core = 6.x +; Information added by Drupal.org packaging script on 2015-06-17 +version = "6.x-2.10" +core = "6.x" +project = "cck" +datestamp = "1434568159" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.install new file mode 100644 index 0000000000000000000000000000000000000000..2e0d3b13ffe25000df9b388a3beecf7b2c34b17d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.install @@ -0,0 +1,153 @@ +<?php +// $Id$ + +/** + * @file + * Implementation of hook_install(). + */ +function userreference_install() { + drupal_load('module', 'content'); + content_notify('install', 'userreference'); +} + +/** + * Implementation of hook_uninstall(). + */ +function userreference_uninstall() { + drupal_load('module', 'content'); + content_notify('uninstall', 'userreference'); +} + +/** + * Implementation of hook_enable(). + * + * Notify content module when this module is enabled. + */ +function userreference_enable() { + drupal_load('module', 'content'); + content_notify('enable', 'userreference'); +} + +/** + * Implementation of hook_disable(). + * + * Notify content module when this module is disabled. + */ +function userreference_disable() { + drupal_load('module', 'content'); + content_notify('disable', 'userreference'); +} + +function userreference_update_last_removed() { + return 4; +} + +/** + * Placeholder update to set newly installed versions to the latest update number. + */ +function userreference_update_6000() { + if ($abort = content_check_update('userreference')) { + return $abort; + } + + $ret = array(); + return $ret; +} + +/** + * Create an index by user reference column for all fields. + */ +function userreference_update_6001(&$sandbox) { + include_once('./'. drupal_get_path('module', 'content') .'/content.install'); + drupal_load('module', 'content'); + + $ret = array(); + + if (!isset($sandbox['progress'])) { + if ($abort = content_check_update('userreference')) { + return $abort; + } + + // Get the latest cache values and schema. + content_clear_type_cache(TRUE, TRUE); + $types = content_types_install(); + + if (empty($types)) { + return $ret; + } + + $sandbox['fields'] = array(); + foreach ($types as $type_name => $fields) { + foreach ($fields as $field) { + if ($field['type'] == 'userreference') { + $sandbox['fields'][] = $field; + } + } + } + + if (empty($sandbox['fields'])) { + return $ret; + } + + $sandbox['progress'] = 0; + $sandbox['visited'] = array(); + } + + $field = $sandbox['fields'][$sandbox['progress']]; + + // We only want to process a field once -- if we hit it a second time, + // that means it's its own table and it should have already been updated. + if (!in_array($field['field_name'], $sandbox['visited'])) { + $db_info = content_database_info($field); + $table = $db_info['table']; + $attributes = $db_info['columns']['uid']; + $column = $attributes['column']; + if (!content_db_index_exists($table, $column)) { + db_add_index($ret, $table, $column, array($column)); + } + $sandbox['visited'][] = $field['field_name']; + } + + $sandbox['progress']++; + $ret['#finished'] = $sandbox['progress'] / count($sandbox['fields']); + + return $ret; +} + +/** + * Convert 'referenceable_status' option from array to integer to match the + * change in the field settings form where the element has been changed from + * a checkboxes element (array) to a radios element (integer). + * + * Reference: @link http://drupal.org/node/416134 @endlink + */ +function userreference_update_6002() { + $ret = array(); + + drupal_load('module', 'content'); + + $result = db_query("SELECT field_name, global_settings FROM {". content_field_tablename() ."} WHERE type = 'userreference'"); + while ($userreference = db_fetch_object($result)) { + $global_settings = unserialize($userreference->global_settings); + + if (isset($global_settings['referenceable_status']) && is_array($global_settings['referenceable_status'])) { + $referenceable_status = array_filter($global_settings['referenceable_status']); + $global_settings['referenceable_status'] = (!empty($referenceable_status) ? 1 : ''); + + // We can't use update_sql() here because of curly braces in serialized + // array. + db_query("UPDATE {". content_field_tablename() ."} SET global_settings = '%s' WHERE field_name = '%s'", serialize($global_settings), $userreference->field_name); + $ret[] = array( + 'success' => TRUE, + 'query' => t("The 'referenceable_status' option for %field has been fixed.", array('%field' => $userreference->field_name)), + ); + } + } + + // Rebuild content caches only if necessary. + if (!empty($ret)) { + content_clear_type_cache(); + } + + return $ret; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.module new file mode 100644 index 0000000000000000000000000000000000000000..daf2b50c8f12a5b77f86da671cb389204a32e766 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.module @@ -0,0 +1,933 @@ +<?php +// $Id$ + +/** + * @file + * Defines a field type for referencing a user from a node. + */ + +/** + * Implementation of hook_menu(). + */ +function userreference_menu() { + $items = array(); + $items['userreference/autocomplete'] = array( + 'title' => 'Userreference autocomplete', + 'page callback' => 'userreference_autocomplete', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK + ); + return $items; +} + +/** + * Implementation of hook_theme(). + */ +function userreference_theme() { + return array( + 'userreference_select' => array( + 'arguments' => array('element' => NULL), + ), + 'userreference_buttons' => array( + 'arguments' => array('element' => NULL), + ), + 'userreference_autocomplete' => array( + 'arguments' => array('element' => NULL), + ), + 'userreference_formatter_default' => array( + 'arguments' => array('element'), + ), + 'userreference_formatter_plain' => array( + 'arguments' => array('element'), + ), + ); +} + +/** + * Implementaion of hook_ctools_plugin_directory(). + */ +function userreference_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && $plugin == 'relationships') { + return 'panels/' . $plugin; + } +} + +/** + * Implementation of hook_field_info(). + */ +function userreference_field_info() { + return array( + 'userreference' => array( + 'label' => t('User reference'), + 'description' => t('Store the ID of a related user as an integer value.'), +// 'content_icon' => 'icon_content_noderef.png', + ), + ); +} + +/** + * Implementation of hook_field_settings(). + */ +function userreference_field_settings($op, $field) { + switch ($op) { + case 'form': + $form = array(); + $form['referenceable_roles'] = array( + '#type' => 'checkboxes', + '#title' => t('User roles that can be referenced'), + '#default_value' => isset($field['referenceable_roles']) && is_array($field['referenceable_roles']) ? array_filter($field['referenceable_roles']) : array(), + '#options' => user_roles(1), + ); + $form['referenceable_status'] = array( + '#type' => 'radios', + '#title' => t('User status that can be referenced'), + '#default_value' => isset($field['referenceable_status']) ? $field['referenceable_status'] : '', + '#options' => array('' => t('All users'), 1 => t('Active users'), 0 => t('Blocked users')), + ); + if (module_exists('views')) { + $views = array('--' => '--'); + $all_views = views_get_all_views(); + foreach ($all_views as $view) { + // Only 'users' views that have fields will work for our purpose. + if ($view->base_table == 'users' && !empty($view->display['default']->display_options['fields'])) { + if ($view->type == 'Default') { + $views[t('Default Views')][$view->name] = $view->name; + } + else { + $views[t('Existing Views')][$view->name] = $view->name; + } + } + } + + $form['advanced'] = array( + '#type' => 'fieldset', + '#title' => t('Advanced - Users that can be referenced (View)'), + '#collapsible' => TRUE, + '#collapsed' => !isset($field['advanced_view']) || $field['advanced_view'] == '--', + ); + if (count($views) > 1) { + $form['advanced']['advanced_view'] = array( + '#type' => 'select', + '#title' => t('View used to select the users'), + '#options' => $views, + '#default_value' => isset($field['advanced_view']) ? $field['advanced_view'] : '--', + '#description' => t('<p>Choose the "Views module" view that selects the users that can be referenced.<br />Note:</p>') . + t('<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the "Referenceable Roles" and "Referenceable Status" settings above. Use the view\'s "filters" section instead.</li><li>Use the view\'s "fields" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view\'s "sort criteria" section to determine the order in which candidate users will be displayed.</li></ul>'), + ); + $form['advanced']['advanced_view_args'] = array( + '#type' => 'textfield', + '#title' => t('View arguments'), + '#default_value' => isset($field['advanced_view_args']) ? $field['advanced_view_args'] : '', + '#required' => FALSE, + '#description' => t('Provide a comma separated list of arguments to pass to the view.'), + ); + } + else { + $form['advanced']['no_view_help'] = array( + '#value' => t('<p>The list of user that can be referenced can be based on a "Views module" view but no appropriate views were found. <br />Note:</p>') . + t('<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the "Referenceable Roles" and "Referenceable Status" settings above. Use the view\'s "filters" section instead.</li><li>Use the view\'s "fields" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view\'s "sort criteria" section to determine the order in which candidate users will be displayed.</li></ul>'), + ); + } + } + return $form; + + case 'save': + $settings = array('referenceable_roles', 'referenceable_status'); + if (module_exists('views')) { + $settings[] = 'advanced_view'; + $settings[] = 'advanced_view_args'; + } + return $settings; + + case 'database columns': + $columns = array( + 'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'index' => TRUE), + ); + return $columns; + + case 'views data': + $data = content_views_field_views_data($field); + $db_info = content_database_info($field); + $table_alias = content_views_tablename($field); + + // Filter : swap the handler to the 'in' operator. + $data[$table_alias][$field['field_name'] .'_uid']['filter']['handler'] = 'content_handler_filter_many_to_one'; + // Argument: get the user name for summaries. + // We need to join a new instance of the users table. + $data["users_$table_alias"]['table']['join']['node'] = array( + 'table' => 'users', + 'field' => 'uid', + 'left_table' => $table_alias, + 'left_field' => $field['field_name'] .'_uid', + ); + $data[$table_alias][$field['field_name'] .'_uid']['argument']['handler'] = 'content_handler_argument_reference'; + $data[$table_alias][$field['field_name'] .'_uid']['argument']['name table'] = "users_$table_alias"; + $data[$table_alias][$field['field_name'] .'_uid']['argument']['name field'] = 'name'; + // Relationship: Add a relationship for related user. + $data[$table_alias][$field['field_name'] .'_uid']['relationship'] = array( + 'base' => 'users', + 'field' => $db_info['columns']['uid']['column'], + 'handler' => 'content_handler_relationship', + 'label' => t($field['widget']['label']), + 'content_field_name' => $field['field_name'], + ); + return $data; + + } +} + +/** + * Implementation of hook_field(). + */ +function userreference_field($op, &$node, $field, &$items, $teaser, $page) { + switch ($op) { + case 'validate': + // Extract uids to check. + $ids = array(); + foreach ($items as $delta => $item) { + if (is_array($item) && !empty($item['uid'])) { + if (is_numeric($item['uid'])) { + $ids[] = $item['uid']; + } + else { + $error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; + if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); + form_set_error($error_element, t('%name: invalid input.', array('%name' => t($field['widget']['label'])))); + } + } + } + // Prevent performance hog if there are no ids to check. + if ($ids) { + $refs = _userreference_potential_references($field, '', NULL, $ids); + foreach ($items as $delta => $item) { + if (is_array($item)) { + $error_element = isset($item['_error_element']) ? $item['_error_element'] : ''; + if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']); + if (!empty($item['uid']) && !isset($refs[$item['uid']])) { + form_set_error($error_element, t('%name: invalid user.', array('%name' => t($field['widget']['label'])))); + } + } + } + } + return $items; + } +} + +/** + * Implementation of hook_content_is_empty(). + */ +function userreference_content_is_empty($item, $field) { + if (empty($item['uid'])) { + return TRUE; + } + return FALSE; +} + +/** + * Implementation of hook_field_formatter_info(). + */ +function userreference_field_formatter_info() { + return array( + 'default' => array( + 'label' => t('Default'), + 'field types' => array('userreference'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + 'plain' => array( + 'label' => t('Plain text'), + 'field types' => array('userreference'), + 'multiple values' => CONTENT_HANDLE_CORE, + ), + ); +} + +/** + * Theme function for 'default' userreference field formatter. + */ +function theme_userreference_formatter_default($element) { + $output = ''; + + if (isset($element['#item']['uid']) && $account = user_load(array('uid' => $element['#item']['uid']))) { + $output = theme('username', $account); + } + return $output; +} + +/** + * Theme function for 'plain' userreference field formatter. + */ +function theme_userreference_formatter_plain($element) { + $output = ''; + if (isset($element['#item']['uid']) && $account = user_load(array('uid' => $element['#item']['uid']))) { + $output = $account->name; + } + return $output; +} + +/** + * Implementation of hook_widget_info(). + * + * We need custom handling of multiple values for the userreference_select + * widget because we need to combine them into a options list rather + * than display multiple elements. + * + * We will use the content module's default handling for default value. + * + * Callbacks can be omitted if default handing is used. + * They're included here just so this module can be used + * as an example for custom modules that might do things + * differently. + */ +function userreference_widget_info() { + return array( + 'userreference_select' => array( + 'label' => t('Select list'), + 'field types' => array('userreference'), + 'multiple values' => CONTENT_HANDLE_MODULE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + 'userreference_buttons' => array( + 'label' => t('Check boxes/radio buttons'), + 'field types' => array('userreference'), + 'multiple values' => CONTENT_HANDLE_MODULE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + 'userreference_autocomplete' => array( + 'label' => t('Autocomplete text field'), + 'field types' => array('userreference'), + 'multiple values' => CONTENT_HANDLE_CORE, + 'callbacks' => array( + 'default value' => CONTENT_CALLBACK_DEFAULT, + ), + ), + ); +} + +/** + * Implementation of FAPI hook_elements(). + * + * Any FAPI callbacks needed for individual widgets can be declared here, + * and the element will be passed to those callbacks for processing. + * + * Drupal will automatically theme the element using a theme with + * the same name as the hook_elements key. + * + * Autocomplete_path is not used by text_widget but other widgets can use it + * (see nodereference and userreference). + */ +function userreference_elements() { + return array( + 'userreference_select' => array( + '#input' => TRUE, + '#columns' => array('uid'), '#delta' => 0, + '#process' => array('userreference_select_process'), + ), + 'userreference_buttons' => array( + '#input' => TRUE, + '#columns' => array('uid'), '#delta' => 0, + '#process' => array('userreference_buttons_process'), + ), + 'userreference_autocomplete' => array( + '#input' => TRUE, + '#columns' => array('name'), '#delta' => 0, + '#process' => array('userreference_autocomplete_process'), + '#autocomplete_path' => FALSE, + ), + ); +} + +/** + * Implementation of hook_widget_settings(). + */ +function userreference_widget_settings($op, $widget) { + switch ($op) { + case 'form': + $form = array(); + $match = isset($widget['autocomplete_match']) ? $widget['autocomplete_match'] : 'contains'; + $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; + if ($widget['type'] == 'userreference_autocomplete') { + $form['autocomplete_match'] = array( + '#type' => 'select', + '#title' => t('Autocomplete matching'), + '#default_value' => $match, + '#options' => array( + 'starts_with' => t('Starts with'), + 'contains' => t('Contains'), + ), + '#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users.'), + ); + $form['size'] = array( + '#type' => 'textfield', + '#title' => t('Size of textfield'), + '#default_value' => $size, + '#element_validate' => array('_element_validate_integer_positive'), + '#required' => TRUE, + ); + } + else { + $form['autocomplete_match'] = array('#type' => 'hidden', '#value' => $match); + $form['size'] = array('#type' => 'hidden', '#value' => $size); + } + $form['reverse_link'] = array( + '#type' => 'checkbox', + '#title' => t('Reverse link'), + '#default_value' => isset($widget['reverse_link']) ? $widget['reverse_link'] : 0, + '#description' => t('If selected, a reverse link back to the referencing node will displayed on the referenced user record.'), + ); + return $form; + + case 'save': + return array('autocomplete_match', 'size', 'reverse_link'); + } +} + +/** + * Implementation of hook_widget(). + * + * Attach a single form element to the form. It will be built out and + * validated in the callback(s) listed in hook_elements. We build it + * out in the callbacks rather than here in hook_widget so it can be + * plugged into any module that can provide it with valid + * $field information. + * + * Content module will set the weight, field name and delta values + * for each form element. This is a change from earlier CCK versions + * where the widget managed its own multiple values. + * + * If there are multiple values for this field, the content module will + * call this function as many times as needed. + * + * @param $form + * the entire form array, $form['#node'] holds node information + * @param $form_state + * the form_state, $form_state['values'][$field['field_name']] + * holds the field's form values. + * @param $field + * the field array + * @param $items + * array of default values for this field + * @param $delta + * the order of this item in the array of subelements (0, 1, 2, etc) + * + * @return + * the form item for a single element for this field + */ +function userreference_widget(&$form, &$form_state, $field, $items, $delta = 0) { + switch ($field['widget']['type']) { + case 'userreference_select': + $element = array( + '#type' => 'userreference_select', + '#default_value' => $items, + ); + break; + + case 'userreference_buttons': + $element = array( + '#type' => 'userreference_buttons', + '#default_value' => $items, + ); + break; + + case 'userreference_autocomplete': + $element = array( + '#type' => 'userreference_autocomplete', + '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL, + '#value_callback' => 'userreference_autocomplete_value', + ); + break; + } + return $element; +} + +/** + * Value for a userreference autocomplete element. + * + * Substitute in the user name for the uid. + */ +function userreference_autocomplete_value($element, $edit = FALSE) { + $field_key = $element['#columns'][0]; + if (!empty($element['#default_value'][$field_key])) { + $value = db_result(db_query("SELECT name FROM {users} WHERE uid = '%d'", $element['#default_value'][$field_key])); + return array($field_key => $value); + } + return array($field_key => NULL); +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function userreference_select_process($element, $edit, $form_state, $form) { + // The userreference_select widget doesn't need to create its own + // element, it can wrap around the optionwidgets_select element. + // Add a validation step where the value can be unwrapped. + $field_key = $element['#columns'][0]; + $element[$field_key] = array( + '#type' => 'optionwidgets_select', + '#default_value' => isset($element['#value']) ? $element['#value'] : '', + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#required' => $element['#required'], + '#description' => $element['#description'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + if (empty($element[$field_key]['#element_validate'])) { + $element[$field_key]['#element_validate'] = array(); + } + array_unshift($element[$field_key]['#element_validate'], 'userreference_optionwidgets_validate'); + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + * The $fields array is in $form['#field_info'][$element['#field_name']]. + */ +function userreference_buttons_process($element, $edit, $form_state, $form) { + // The userreference_select widget doesn't need to create its own + // element, it can wrap around the optionwidgets_select element. + // Add a validation step where the value can be unwrapped. + $field_key = $element['#columns'][0]; + $element[$field_key] = array( + '#type' => 'optionwidgets_buttons', + '#default_value' => isset($element['#value']) ? $element['#value'] : '', + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#required' => $element['#required'], + '#description' => $element['#description'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + if (empty($element[$field_key]['#element_validate'])) { + $element[$field_key]['#element_validate'] = array(); + } + array_unshift($element[$field_key]['#element_validate'], 'userreference_optionwidgets_validate'); + return $element; +} + +/** + * Process an individual element. + * + * Build the form element. When creating a form using FAPI #process, + * note that $element['#value'] is already set. + * + */ +function userreference_autocomplete_process($element, $edit, $form_state, $form) { + // The userreference autocomplete widget doesn't need to create its own + // element, it can wrap around the text_textfield element and add an autocomplete + // path and some extra processing to it. + // Add a validation step where the value can be unwrapped. + $field_key = $element['#columns'][0]; + + $element[$field_key] = array( + '#type' => 'text_textfield', + '#default_value' => isset($element['#value']) ? $element['#value'] : '', + '#autocomplete_path' => 'userreference/autocomplete/'. $element['#field_name'], + // The following values were set by the content module and need + // to be passed down to the nested element. + '#title' => $element['#title'], + '#required' => $element['#required'], + '#description' => $element['#description'], + '#field_name' => $element['#field_name'], + '#type_name' => $element['#type_name'], + '#delta' => $element['#delta'], + '#columns' => $element['#columns'], + ); + if (empty($element[$field_key]['#element_validate'])) { + $element[$field_key]['#element_validate'] = array(); + } + array_unshift($element[$field_key]['#element_validate'], 'userreference_autocomplete_validate'); + + // Used so that hook_field('validate') knows where to flag an error. + $element['_error_element'] = array( + '#type' => 'value', + // Wrapping the element around a text_textfield element creates a + // nested element, so the final id will look like 'field-name-0-uid-uid'. + '#value' => implode('][', array_merge($element['#parents'], array($field_key, $field_key))), + ); + return $element; +} + +/** + * Validate a select/buttons element. + * + * Remove the wrapper layer and set the right element's value. + * We don't know exactly where this element is, so we drill down + * through the element until we get to our key. + * + * We use $form_state['values'] instead of $element['#value'] + * to be sure we have the most accurate value when other modules + * like optionwidgets are using #element_validate to alter the value. + */ +function userreference_optionwidgets_validate($element, &$form_state) { + $field_key = $element['#columns'][0]; + + $value = $form_state['values']; + $new_parents = array(); + foreach ($element['#parents'] as $parent) { + $value = $value[$parent]; + // Use === to be sure we get right results if parent is a zero (delta) value. + if ($parent === $field_key) { + $element['#parents'] = $new_parents; + form_set_value($element, $value, $form_state); + break; + } + $new_parents[] = $parent; + } +} + +/** + * Validate an autocomplete element. + * + * Remove the wrapper layer and set the right element's value. + * This will move the nested value at 'field-name-0-uid-uid' + * back to its original location, 'field-name-0-uid'. + */ +function userreference_autocomplete_validate($element, &$form_state) { + $field_name = $element['#field_name']; + $type_name = $element['#type_name']; + $field = content_fields($field_name, $type_name); + $field_key = $element['#columns'][0]; + $value = $element['#value'][$field_key]; + $uid = NULL; + if (!empty($value)) { + $reference = _userreference_potential_references($field, $value, 'equals', NULL, 1); + if (empty($reference)) { + form_error($element[$field_key], t('%name: found no valid user with that name.', array('%name' => t($field['widget']['label'])))); + } + else { + $uid = key($reference); + } + } + form_set_value($element, $uid, $form_state); +} + +/** + * Implementation of hook_allowed_values(). + */ +function userreference_allowed_values($field) { + $references = _userreference_potential_references($field); + + $options = array(); + foreach ($references as $key => $value) { + $options[$key] = $value['rendered']; + } + + return $options; +} + +/** + * Fetch an array of all candidate referenced 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 description. + * @param $string + * Optional string to filter usernames on (used by autocomplete) + * @param $match + * Operator to match filtered name against, can be any of: + * 'contains', 'equals', 'starts_with' + * @param $ids + * Optional user ids to lookup (the $string and $match arguments will be + * ignored). + * @param $limit + * If non-zero, limit the size of the result set. + * + * @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 _userreference_potential_references($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { + static $results = array(); + + // Create unique id for static cache. + $cid = $field['field_name'] .':'. $match .':'. ($string !== '' ? $string : implode('-', $ids)) .':'. $limit; + if (!isset($results[$cid])) { + $references = FALSE; + if (module_exists('views') && !empty($field['advanced_view']) && $field['advanced_view'] != '--') { + $references = _userreference_potential_references_views($field, $string, $match, $ids, $limit); + } + // If the view doesn't exist, we got FALSE, and fallback to the regular 'standard mode'. + + if ($references === FALSE) { + $references = _userreference_potential_references_standard($field, $string, $match, $ids, $limit); + } + + // Store the results. + $results[$cid] = !empty($references) ? $references : array(); + } + + return $results[$cid]; +} + +/** + * Helper function for _userreference_potential_references(): + * case of Views-defined referenceable users. + */ +function _userreference_potential_references_views($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { + $view_name = $field['advanced_view']; + + if ($view = views_get_view($view_name)) { + // We add a display, and let it derive from the 'default' display. + // TODO: We should let the user pick a display in the fields settings - sort of requires AHAH... + $display = $view->add_display('content_references'); + $view->set_display($display); + + // TODO from merlinofchaos on IRC : arguments using summary view can defeat the style setting. + // We might also need to check if there's an argument, and set *its* style_plugin as well. + $view->display_handler->set_option('style_plugin', 'content_php_array_autocomplete'); + $view->display_handler->set_option('row_plugin', 'fields'); + // Used in content_plugin_style_php_array::render(), to get + // the 'field' to be used as title. + $view->display_handler->set_option('content_title_field', 'name'); + + // Additional options to let content_plugin_display_references::query() + // narrow the results. + $options = array( + 'table' => 'users', + 'field_string' => 'name', + 'string' => $string, + 'match' => $match, + 'field_id' => 'uid', + 'ids' => $ids, + ); + $view->display_handler->set_option('content_options', $options); + + // TODO : for consistency, a fair amount of what's below + // should be moved to content_plugin_display_references + + // Limit result set size. + $limit = isset($limit) ? $limit : 0; + $view->display_handler->set_option('items_per_page', $limit); + + // Get arguments for the view. + if (!empty($field['advanced_view_args'])) { + // TODO: Support Tokens using token.module ? + $view_args = array_map('trim', explode(',', $field['advanced_view_args'])); + } + else { + $view_args = array(); + } + + // We do need name field, so add it if not present (unlikely, but...) + $fields = $view->get_items('field', $display); + if (!isset($fields['name'])) { + $view->add_item($display, 'field', 'users', 'name'); + } + + // If not set, make all fields inline and define a separator. + $options = $view->display_handler->get_option('row_options'); + if (empty($options['inline'])) { + $options['inline'] = drupal_map_assoc(array_keys($view->get_items('field', $display))); + } + if (empty($options['separator'])) { + $options['separator'] = '-'; + } + $view->display_handler->set_option('row_options', $options); + + // Make sure the query is not cached + $view->is_cacheable = FALSE; + + // Get the results. + $result = $view->execute_display($display, $view_args); + } + else { + $result = FALSE; + } + + return $result; +} + +/** + * Helper function for _userreference_potential_references(): + * referenceable users defined by user role and status + */ +function _userreference_potential_references_standard($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) { + $where = array(); + $args = array(); + $join = array(); + + if ($string !== '') { + $like = $GLOBALS["db_type"] == 'pgsql' ? "ILIKE" : "LIKE"; + $match_clauses = array( + 'contains' => "$like '%%%s%%'", + 'equals' => "= '%s'", + 'starts_with' => "$like '%s%%'", + ); + $where[] = 'u.name '. (isset($match_clauses[$match]) ? $match_clauses[$match] : $match_clauses['contains']); + $args[] = $string; + } + elseif ($ids) { + $where[] = 'u.uid IN (' . db_placeholders($ids) . ')'; + $args = array_merge($args, $ids); + } + else { + $where[] = "u.uid > 0"; + } + + $roles = array(); + if (isset($field['referenceable_roles']) && is_array($field['referenceable_roles'])) { + // keep only selected checkboxes + $roles = array_filter($field['referenceable_roles']); + // filter invalid values that seems to get through sometimes ?? + $roles = array_intersect(array_keys(user_roles(1)), $roles); + } + if (!empty($roles) && !in_array(DRUPAL_AUTHENTICATED_RID, $roles)) { + $where[] = "r.rid IN (". implode($roles, ',') .")"; + $join[] = 'LEFT JOIN {users_roles} r ON u.uid = r.uid'; + } + + if (isset($field['referenceable_status']) && is_numeric($field['referenceable_status'])) { + $where[] = 'u.status = %d'; + $args[] = $field['referenceable_status']; + } + + $users = array(); + $where_clause = $where ? 'WHERE ('. implode(') AND (', $where) .')' : ''; + $result = db_query('SELECT u.name, u.uid FROM {users} u '. implode(' ', $join) ." $where_clause ORDER BY u.name ASC", $args); + while ($user = db_fetch_object($result)) { + $users[$user->uid] = array( + 'title' => $user->name, + 'rendered' => check_plain($user->name), + ); + } + return $users; +} + +/** + * Menu callback; Retrieve a pipe delimited string of autocomplete suggestions for existing users + */ +function userreference_autocomplete($field_name, $string = '') { + $fields = content_fields(); + $field = $fields[$field_name]; + $match = isset($field['widget']['autocomplete_match']) ? $field['widget']['autocomplete_match'] : 'contains'; + $matches = array(); + + $references = _userreference_potential_references($field, $string, $match, array(), 10); + foreach ($references as $id => $row) { + // Add a class wrapper for a few required CSS overrides. + $matches[$row['title']] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>'; + } + drupal_json($matches); +} + +/** + * Implementation of hook_user(). + */ +function userreference_user($type, &$edit, &$account) { + switch ($type) { + case 'load': + // Only add links if we are on the user 'view' page. + if (arg(0) != 'user' || arg(2)) { + return; + } + // find CCK userreference field tables + // search through them for matching user ids and load those nodes + $additions = array(); + $types = content_types(); + + // Find the table and columns to search through, if the same + // table comes up in more than one content type, we only need + // to search it once. + $search_tables = array(); + foreach ($types as $type_name => $type) { + foreach ($type['fields'] as $field) { + // Only add tables when reverse link has been selected. + if ($field['type'] == 'userreference' && !empty($field['widget']['reverse_link'])) { + $db_info = content_database_info($field); + $search_tables[$db_info['table']][] = $db_info['columns']['uid']['column']; + } + } + } + foreach ($search_tables as $table => $columns) { + foreach ($columns as $column) { + $ids = db_query(db_rewrite_sql("SELECT DISTINCT(n.nid), n.title, n.type FROM {node} n LEFT JOIN {". $table ."} f ON n.vid = f.vid WHERE f.". $column ."=". $account->uid. " AND n.status = 1")); + while ($data = db_fetch_object($ids)) { + $additions[$data->type][$data->nid] = $data->title; + } + } + } + $account->userreference = $additions; + break; + + case 'view': + if (!empty($account->userreference)) { + $node_types = content_types(); + $additions = array(); + $values = array(); + foreach ($account->userreference as $node_type => $nodes) { + foreach ($nodes as $nid => $title) { + $values[$node_type][] = l($title, 'node/'. $nid); + } + if (isset($values[$node_type])) { + $additions[] = array( + '#type' => 'user_profile_item', + '#title' => check_plain($node_types[$node_type]['name']), + '#value' => theme('item_list', $values[$node_type]), + ); + } + } + if ($additions) { + $account->content['userreference'] = $additions + array( + '#type' => 'user_profile_category', + '#attributes' => array('class' => 'user-member'), + '#title' => t('Related content'), + '#weight' => 10, + ); + } + } + break; + } +} + +/** + * FAPI theme for an individual elements. + * + * The textfield or select is already rendered by the + * textfield or select themes and the html output + * lives in $element['#children']. Override this theme to + * make custom changes to the output. + * + * $element['#field_name'] contains the field name + * $element['#delta] is the position of this element in the group + */ +function theme_userreference_select($element) { + return $element['#children']; +} + +function theme_userreference_buttons($element) { + return $element['#children']; +} + +function theme_userreference_autocomplete($element) { + return $element['#children']; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.rules.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.rules.inc new file mode 100644 index 0000000000000000000000000000000000000000..454df99cae17c6acf6c2e865f4e4079468b17556 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.rules.inc @@ -0,0 +1,62 @@ +<?php +// $Id$ + +/** + * @file + * Provides additional rules support for userreference fields. + */ + +/** + * Implementation of hook_rules_action_info() + */ +function userreference_rules_action_info() { + $info = array(); + $info['userreference_rules_action_load'] = array( + 'label' => t('Load a referenced user'), + 'arguments' => array( + 'node' => array( + 'type' => 'node', + 'label' => t('Content containing the user reference field'), + ), + ), + 'new variables' => array( + 'referenced_user' => array( + 'type' => 'user', + 'label' => t('Referenced user'), + ), + ), + 'module' => 'CCK', + 'help' => t('Note that if the field has multiple values, only the first user will be loaded.'), + ); + return $info; +} + +function userreference_rules_action_load($node, $settings) { + $uid = $node->{$settings['field']}[0]['uid']; + if (isset($uid)) { + $user = user_load(array('uid' => $uid)); + return array('referenced_user' => $user); + } +} + +function userreference_rules_action_load_form($settings, &$form) { + $settings += array('field' => ''); + $options = content_rules_get_field_names_by_type('userreference'); + $form['settings']['field'] = array( + '#type' => 'select', + '#title' => t('Field'), + '#default_value' => $settings['field'], + '#options' => $options, + '#required' => TRUE, + '#disabled' => empty($options), + '#description' => empty($options) ? t('There are no userreference fields defined.') : '', + ); +} + +/** + * Helps upgrading from the workflow-ng action. + * "workflow_ng_action_load_referenced_user" to the equivalent rules action. + */ +function workflow_ng_action_load_referenced_user_upgrade(&$element) { + $element['#name'] = 'userreference_rules_action_load'; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/tests/content.crud.test b/drupal/sites/default/boinc/modules/contrib/cck/tests/content.crud.test new file mode 100644 index 0000000000000000000000000000000000000000..070a3d0a1afe1778425c6f42206ecb02ed7b42f0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/tests/content.crud.test @@ -0,0 +1,1236 @@ +<?php +// $Id$ + +// TODO: +// - Test search indexing +// - Test values reordering with preview and failed validation + +/** + * Base class for CCK CRUD tests. + * Defines many helper functions useful for writing CCK CRUD tests. + */ +class ContentCrudTestCase extends DrupalWebTestCase { + var $enabled_schema = FALSE; + var $content_types = array(); + var $nodes = array(); + var $last_field = NULL; + var $next_field_n = 1; + + /** + * Enable CCK, Text, and Schema modules. + */ + function setUp() { + $args = func_get_args(); + $modules = array_merge(array('content', 'schema', 'text'), $args); + call_user_func_array(array('parent','setUp'), $modules); + module_load_include('inc', 'content', 'includes/content.crud'); + } + + // Database schema related helper functions + + /** + * Checks that the database itself and the reported database schema match the + * expected columns for the given tables. + * @param $tables An array containing the key 'per_field' and/or the key 'per_type'. + * These keys should have array values with table names as the keys (without the 'content_' / 'content_type_' prefix) + * These keys should have either NULL value to indicate the table should be absent, or + * array values containing column names. The column names can themselves be arrays, in + * which case the contents of the array are treated as column names and prefixed with + * the array key. + * + * For example, if called with the following as an argument: + * array( + * 'per_field' => array( + * 'st_f1' => array('delta', 'field_f1' => array('value, 'format')), + * 'st_f2' => NULL, // no content_field_f2 table + * ), + * 'per_type' => array( + * 'st_t1' => array('field_f2' => array('value'), 'field_f3' => array('value', 'format')), + * 'st_t2' => array(), // only 'nid' and 'vid' columns + * 'st_t3' => NULL, // no content_type_t3 table + * ), + * ) + * Then the database and schema will be checked to ensure that: + * content_st_f1 table contains fields nid, vid, delta, field_f1_value, field_f1_format + * content_st_f2 table is absent + * content_type_st_t1 table contains fields nid, vid, field_f2_value, field_f3_value, field_f3_format + * content_type_st_t2 table contains fields nid, vid + * content_type_st_t3 table is absent + */ + function assertSchemaMatchesTables($tables) { + $groups = array('per_field' => 'content_', 'per_type' => 'content_type_'); + + foreach ($groups as $group => $table_prefix) { + if (isset($tables[$group])) { + foreach ($tables[$group] as $entity => $columns) { + if (isset($columns)) { + $db_columns = array('nid', 'vid'); + foreach ($columns as $prefix => $items) { + if (is_array($items)) { + foreach ($items as $item) { + $db_columns[] = $prefix .'_'. $item; + } + } + else { + $db_columns[] = $items; + } + } + $this->_assertSchemaMatches($table_prefix . $entity, $db_columns); + } + else { + $this->_assertTableNotExists($table_prefix . $entity); + } + } + } + } + } + + /** + * Helper function for assertSchemaMatchesTables + * Checks that the given database table does NOT exist + * @param $table Name of the table to check + */ + function _assertTableNotExists($table) { + $this->assertFalse(db_table_exists($table), t('Table !table is absent', array('!table' => $table))); + } + + /** + * Helper function for assertSchemaMatchesTables + * Checks that the database and schema for the given table contain only the expected fields. + * @param $table Name of the table to check + * @param $columns Array of column names + */ + function _assertSchemaMatches($table, $columns) { + // First test: check the expected structure matches the stored schema. + $schema = drupal_get_schema($table, TRUE); + $mismatches = array(); + if ($schema === FALSE) { + $mismatches[] = t('table does not exist'); + } + else { + $fields = $schema['fields']; + foreach ($columns as $field) { + if (!isset($fields[$field])) { + $mismatches[] = t('field !field is missing from table', array('!field' => $field)); + } + } + $columns_reverse = array_flip($columns); + foreach ($fields as $name => $info) { + if(!isset($columns_reverse[$name])) { + $mismatches[] = t('table contains unexpected field !field', array('!field' => $name)); + } + } + } + $this->assertEqual(count($mismatches), 0, t('Table !table matches schema: !details', + array('!table' => $table, '!details' => implode($mismatches, ', ')))); + + // Second test: check the schema matches the actual db structure. + // This is the part that relies on schema.module. + if (!$this->enabled_schema) { + $this->enabled_schema = module_exists('schema'); + } + if ($this->enabled_schema) { + // Clunky workaround for http://drupal.org/node/215198 + $prefixed_table = db_prefix_tables('{'. $table .'}'); + $inspect = schema_invoke('inspect', $prefixed_table); + $inspect = isset($inspect[$table]) ? $inspect[$table] : NULL; + $compare = schema_compare_table($schema, $inspect); + if ($compare['status'] == 'missing') { + $compare['reasons'] = array(t('table does not exist')); + } + } + else { + $compare = array('status' => 'unknown', 'reasons' => array(t('cannot enable schema module'))); + } + $this->assertEqual($compare['status'], 'same', t('Table schema for !table matches database: !details', + array('!table' => $table, '!details' => implode($compare['reasons'], ', ')))); + } + + // Node data helper functions + + /** + * Helper function for assertNodeSaveValues. Recursively checks that + * all the keys of a table are present in a second and have the same value. + */ + function _compareArrayForChanges($fields, $data, $message, $prefix = '') { + foreach ($fields as $key => $value) { + $newprefix = ($prefix == '') ? $key : $prefix .']['. $key; + if (is_array($value)) { + $compare_to = isset($data[$key]) ? $data[$key] : array(); + $this->_compareArrayForChanges($value, $compare_to, $message, $newprefix); + } + else { + $this->assertEqual($value, $data[$key], t($message, array('!key' => $newprefix))); + } + } + } + + /** + * Checks that after a node is saved using node_save, the values to be saved + * match up with the output from node_load. + * @param $node Either a node object, or the index of an acquired node + * @param $values Array of values to be merged with the node and passed to node_save + * @return The values array + */ + function assertNodeSaveValues($node, $values) { + if (is_numeric($node) && isset($this->nodes[$node])) { + $node = $this->nodes[$node]; + } + $node = $values + (array)$node; + $node = (object)$node; + node_save($node); + $this->assertNodeValues($node, $values); + return $values; + } + + /** + * Checks that the output from node_load matches the expected values. + * @param $node Either a node object, or the index of an acquired node (only the nid field is used) + * @param $values Array of values to check against node_load. The node object must contain the keys in the array, + * and the values must be equal, but the node object may also contain other keys. + */ + function assertNodeValues($node, $values) { + if (is_numeric($node) && isset($this->nodes[$node])) { + $node = $this->nodes[$node]; + } + $node = node_load($node->nid, NULL, TRUE); + $this->_compareArrayForChanges($values, (array)$node, 'Node data [!key] is correct'); + } + + /** + * Checks that the output from node_load is missing certain fields + * @param $node Either a node object, or the index of an acquired node (only the nid field is used) + * @param $fields Array containing a list of field names + */ + function assertNodeMissingFields($node, $fields) { + if (is_numeric($node) && isset($this->nodes[$node])) { + $node = $this->nodes[$node]; + } + $node = (array)node_load($node->nid, NULL, TRUE); + foreach ($fields as $field) { + $this->assertFalse(isset($node[$field]), t('Node should be lacking field !key', array('!key' => $field))); + } + } + + /** + * Creates random values for a text field + * @return An array containing a value key and a format key + */ + function createRandomTextFieldData() { + return array( + 'value' => '!SimpleTest! test value' . $this->randomName(60), + 'format' => 2, + ); + } + + // Login/user helper functions + + /** + * Creates a user / role with certain permissions and then logs in as that user + * @param $permissions Array containing list of permissions. If not given, defaults to + * access content, administer content types, administer nodes and administer filters. + */ + function loginWithPermissions($permissions = NULL) { + if (!isset($permissions)) { + $permissions = array( + 'access content', + 'administer content types', + 'administer nodes', + 'administer filters', + ); + } + $user = $this->drupalCreateUser($permissions); + $this->drupalLogin($user); + } + + // Creation helper functions + + /** + * Creates a number of content types with predictable names (simpletest_t1 ... simpletest_tN) + * These content types can later be accessed via $this->content_types[0 ... N-1] + * @param $count Number of content types to create + */ + function acquireContentTypes($count) { + $this->content_types = array(); + for ($i = 0; $i < $count; $i++) { + $name = 'simpletest_t'. ($i + 1); + $this->content_types[$i] = $this->drupalCreateContentType(array( + 'name' => $name, + 'type' => $name, + )); + } + content_clear_type_cache(); + } + + /** + * Creates a number of nodes of each acquired content type. + * Remember to call acquireContentTypes() before calling this, else the content types won't exist. + * @param $count Number of nodes to create per acquired content type (defaults to 1) + */ + function acquireNodes($count = 1) { + $this->nodes = array(); + foreach ($this->content_types as $content_type) { + for ($i = 0; $i < $count; $i++) { + $this->nodes[] = $this->drupalCreateNode(array('type' => $content_type->type)); + } + } + } + + /** + * Creates a field instance with a predictable name. Also makes all future calls to functions + * which take an optional field use this one as the default. + * @param $settings Array to be passed to content_field_instance_create. If the field_name + * or type_name keys are missing, then they will be added. The default field name is + * simpletest_fN, where N is 1 for the first created field, and increments. The default + * type name is type name of the $content_type argument. + * @param $content_type Either a content type object, or the index of an acquired content type + * @return The newly created field instance. + */ + function createField($settings, $content_type = 0) { + if (is_numeric($content_type) && isset($this->content_types[$content_type])) { + $content_type = $this->content_types[$content_type]; + } + $defaults = array( + 'field_name' => 'simpletest_f'. $this->next_field_n++, + 'type_name' => $content_type->type, + ); + $settings = $settings + $defaults; + $this->last_field = content_field_instance_create($settings); + return $this->last_field; + } + + /** + * Creates a textfield instance. Identical to createField() except it ensures that the text module + * is enabled, and adds default settings of type (text) and widget_type (text_textfield) if they + * are not given in $settings. + * @sa createField() + */ + function createFieldText($settings, $content_type = 0) { + $defaults = array( + 'type' => 'text', + 'widget_type' => 'text_textfield', + ); + $settings = $settings + $defaults; + return $this->createField($settings, $content_type); + } + + // Field manipulation helper functions + + /** + * Updates a field instance. Also makes all future calls to functions which take an optional + * field use the updated one as the default. + * @param $settings New settings for the field instance. If the field_name or type_name keys + * are missing, then they will be taken from $field. + * @param $field The field instance to update (defaults to the last worked upon field) + * @return The updated field instance. + */ + function updateField($settings, $field = NULL) { + if (!isset($field)) { + $field = $this->last_field; + } + $defaults = array( + 'field_name' => $field['field_name'], + 'type_name' => $field['type_name'] , + ); + $settings = $settings + $defaults; + $this->last_field = content_field_instance_update($settings); + return $this->last_field; + } + + /** + * Makes a copy of a field instance on a different content type, effectively sharing the field with a new + * content type. Also makes all future calls to functions which take an optional field use the shared one + * as the default. + * @param $new_content_type Either a content type object, or the index of an acquired content type + * @param $field The field instance to share (defaults to the last worked upon field) + * @return The shared (newly created) field instance. + */ + function shareField($new_content_type, $field = NULL) { + if (!isset($field)) { + $field = $this->last_field; + } + if (is_numeric($new_content_type) && isset($this->content_types[$new_content_type])) { + $new_content_type = $this->content_types[$new_content_type]; + } + $field['type_name'] = $new_content_type->type; + $this->last_field = content_field_instance_create($field); + return $this->last_field; + } + + /** + * Deletes an instance of a field. + * @param $content_type Either a content type object, or the index of an acquired content type (used only + * to get field instance type name). + * @param $field The field instance to delete (defaults to the last worked upon field, used only to get + * field instance field name). + */ + function deleteField($content_type, $field = NULL) { + if (!isset($field)) { + $field = $this->last_field; + } + if (is_numeric($content_type) && isset($this->content_types[$content_type])) { + $content_type = $this->content_types[$content_type]; + } + content_field_instance_delete($field['field_name'], $content_type->type); + } +} + +class ContentCrudBasicTest extends ContentCrudTestCase { + function getInfo() { + return array( + 'name' => t('CRUD - Basic API tests'), + 'description' => t('Tests the field CRUD (create, read, update, delete) API. <strong>Requires <a href="@schema_link">Schema module</a>.</strong>', array('@schema_link' => 'http://www.drupal.org/project/schema')), + 'group' => t('CCK'), + ); + } + + function setUp() { + parent::setUp(); + $this->acquireContentTypes(1); + } + + function testBasic() { + // Create a field with both field and instance settings. + $field = $this->createFieldText(array('widget_type' => 'text_textarea', 'text_processing' => 1, 'rows' => 5), 0); + + + // Check that collapse and expand are inverse. + $fields = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $this->content_types[0]->type)); + $field1 = array_pop($fields); + + $field2 = content_field_instance_collapse($field1); + $field3 = content_field_instance_expand($field2); + $field4 = content_field_instance_collapse($field3); + + $this->assertIdentical($field1, $field3, 'collapse then expand is identity'); + $this->assertIdentical($field2, $field4, 'expand then collapse is identity'); + + + // Check that collapse and expand are both final + // (e.g. do not further alter the data when called multiple times). + $fields = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $this->content_types[0]->type)); + $field1 = array_pop($fields); + + $field2 = content_field_instance_collapse($field1); + $field3 = content_field_instance_collapse($field2); + $this->assertIdentical($field2, $field3, 'collapse is final'); + + $field2 = content_field_instance_expand($field1); + $field3 = content_field_instance_expand($field2); + $this->assertIdentical($field2, $field3, 'expand is final'); + + + // Check that updating a field as is leaves it unchanged. + $fields = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $this->content_types[0]->type)); + $field1 = array_pop($fields); + $field2 = content_field_instance_update($field1); + $fields = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $this->content_types[0]->type)); + $field3 = array_pop($fields); + + $this->assertIdentical($field1, $field3, 'read, update, read is identity'); + } +} + +class ContentCrudSingleToMultipleTest extends ContentCrudTestCase { + function getInfo() { + return array( + 'name' => t('CRUD - Single to multiple'), + 'description' => t('Tests the field CRUD (create, read, update, delete) API by creating a single value field and changing it to a multivalue field, sharing it between several content types. <strong>Requires <a href="@schema_link">Schema module</a>.</strong>', array('@schema_link' => 'http://www.drupal.org/project/schema')), + 'group' => t('CCK'), + ); + } + + function setUp() { + parent::setUp(); + $this->loginWithPermissions(); + $this->acquireContentTypes(3); + $this->acquireNodes(); + } + + function testSingleToMultiple() { + // Create a simple text field + $this->createFieldText(array('text_processing' => 1)); + $target_schema = array( + 'per_type' => array( + 'simpletest_t1' => array('simpletest_f1' => array('value', 'format')) + ), + 'per_field' => array(), + ); + $this->assertSchemaMatchesTables($target_schema); + $node0values = $this->assertNodeSaveValues(0, array( + 'simpletest_f1' => array( + 0 => $this->createRandomTextFieldData(), + ) + )); + + // Change the text field to allow multiple values + $this->updateField(array('multiple' => 1)); + $target_schema = array( + 'per_type' => array( + 'simpletest_t1' => array(), + ), + 'per_field' => array( + 'simpletest_f1' => array('delta', 'simpletest_f1' => array('value', 'format')), + ), + ); + $this->assertSchemaMatchesTables($target_schema); + $this->assertNodeValues(0, $node0values); + + // Share the text field with 2 additional types t2 and t3. + for ($share_with_content_type = 1; $share_with_content_type <= 2; $share_with_content_type++) { + $this->shareField($share_with_content_type); + // There should be a new 'empty' per-type table for each content type that has fields. + $target_schema['per_type']['simpletest_t'. ($share_with_content_type + 1)] = array(); + $this->assertSchemaMatchesTables($target_schema); + // The acquired node index will match the content type index as exactly one node is acquired per content type + $this->assertNodeSaveValues($share_with_content_type, array( + 'simpletest_f1' => array( + 0 => $this->createRandomTextFieldData(), + ) + )); + } + + // Delete the text field from all content types + for ($delete_from_content_type = 2; $delete_from_content_type >= 0; $delete_from_content_type--) { + $this->deleteField($delete_from_content_type); + // Content types that don't have fields any more shouldn't have any per-type table. + $target_schema['per_type']['simpletest_t'. ($delete_from_content_type + 1)] = NULL; + // After removing the last instance, there should be no table for the field either. + if ($delete_from_content_type == 0) { + $target_schema['per_field']['simpletest_f1'] = NULL; + } + $this->assertSchemaMatchesTables($target_schema); + // The acquired node index will match the content type index as exactly one node is acquired per content type + $this->assertNodeMissingFields($this->nodes[$delete_from_content_type], array('simpletest_f1')); + } + } +} + +class ContentCrudMultipleToSingleTest extends ContentCrudTestCase { + function getInfo() { + return array( + 'name' => t('CRUD - Multiple to single'), + 'description' => t('Tests the field CRUD (create, read, update, delete) API by creating a multivalue field and changing it to a single value field, sharing it between several content types. <strong>Requires <a href="@schema_link">Schema module</a>.</strong>', array('@schema_link' => 'http://www.drupal.org/project/schema')), + 'group' => t('CCK'), + ); + } + + function setUp() { + parent::setUp(); + $this->loginWithPermissions(); + $this->acquireContentTypes(3); + $this->acquireNodes(); + } + + function testMultipleToSingle() { + // Create a multivalue text field + $this->createFieldText(array('text_processing' => 1, 'multiple' => 1)); + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + 'simpletest_t1' => array(), + ), + 'per_field' => array( + 'simpletest_f1' => array('delta', 'simpletest_f1' => array('value', 'format')), + ), + )); + $this->assertNodeSaveValues(0, array( + 'simpletest_f1' => array( + 0 => $this->createRandomTextFieldData(), + 1 => $this->createRandomTextFieldData(), + 2 => $this->createRandomTextFieldData(), + ) + )); + + // Change to a simple text field + $this->updateField(array('multiple' => 0)); + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + 'simpletest_t1' => array('simpletest_f1' => array('value', 'format')), + ), + 'per_field' => array( + 'simpletest_f1' => NULL, + ), + )); + $node0values = $this->assertNodeSaveValues(0, array( + 'simpletest_f1' => array( + 0 => $this->createRandomTextFieldData(), + ) + )); + + // Share the text field with other content type + $this->shareField(1); + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + 'simpletest_t1' => array(), + 'simpletest_t2' => array(), + ), + 'per_field' => array( + 'simpletest_f1' => array('simpletest_f1' => array('value', 'format')), + ), + )); + $node1values = $this->assertNodeSaveValues(1, array( + 'simpletest_f1' => array( + 0 => $this->createRandomTextFieldData(), + ) + )); + $this->assertNodeValues(0, $node0values); + + // Share the text field with a 3rd type + $this->shareField(2); + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + 'simpletest_t1' => array(), + 'simpletest_t2' => array(), + 'simpletest_t3' => array(), + ), + 'per_field' => array( + 'simpletest_f1' => array('simpletest_f1' => array('value', 'format')), + ), + )); + $this->assertNodeSaveValues(2, array( + 'simpletest_f1' => array( + 0 => $this->createRandomTextFieldData(), + ) + )); + $this->assertNodeValues(1, $node1values); + $this->assertNodeValues(0, $node0values); + + // Remove text field from 3rd type + $this->deleteField(2); + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + 'simpletest_t1' => array(), + 'simpletest_t2' => array(), + 'simpletest_t3' => NULL, + ), + 'per_field' => array( + 'simpletest_f1' => array('simpletest_f1' => array('value', 'format')), + ), + )); + $this->assertNodeMissingFields($this->nodes[2], array('simpletest_f1')); + + // Remove text field from 2nd type (field isn't shared anymore) + $this->deleteField(1); + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + 'simpletest_t1' => array('simpletest_f1' => array('value', 'format')), + 'simpletest_t2' => NULL, + 'simpletest_t3' => NULL, + ), + 'per_field' => array( + 'simpletest_f1' => NULL, + ), + )); + $this->assertNodeMissingFields(1, array('simpletest_f1')); + $this->assertNodeValues(0, $node0values); + + // Remove text field from original type + $this->deleteField(0); + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + 'simpletest_t1' => NULL, + 'simpletest_t2' => NULL, + 'simpletest_t3' => NULL, + ), + 'per_field' => array( + 'simpletest_f1' => NULL, + ), + )); + $this->assertNodeMissingFields(0, array('simpletest_f1')); + } +} + +class ContentUICrud extends ContentCrudTestCase { + function getInfo() { + return array( + 'name' => t('Admin UI'), + 'description' => t('Tests the CRUD (create, read, update, delete) operations for content fields via the UI. <strong>Requires <a href="@schema_link">Schema module</a>.</strong>', array('@schema_link' => 'http://www.drupal.org/project/schema')), + 'group' => t('CCK'), + ); + } + + function setUp() { + parent::setUp('fieldgroup'); + $this->loginWithPermissions(); + } + + function testAddFieldUI() { + // Add a content type with a random name (to avoid schema module problems). + $type1 = 'simpletest'. mt_rand(); + $type1_name = $this->randomName(10); + $edit = array( + 'type' => $type1, + 'name' => $type1_name, + ); + $this->drupalPost('admin/content/types/add', $edit, 'Save content type'); + $admin_type1_url = 'admin/content/node-type/'. $type1; + + // Create a text field via the UI. + $field_name = strtolower($this->randomName(10)); + $field_label = $this->randomName(10); + $edit = array( + '_add_new_field[label]' => $field_label, + '_add_new_field[field_name]' => $field_name, + '_add_new_field[type]' => 'text', + '_add_new_field[widget_type]' => 'text_textfield', + ); + $this->drupalPost($admin_type1_url .'/fields', $edit, 'Save'); + $this->assertRaw('These settings apply only to the <em>'. $field_label .'</em> field', 'Field settings page displayed'); + $this->assertRaw('Size of textfield', 'Field and widget types correct.'); + $this->assertNoRaw('Change basic information', 'No basic information displayed'); + $field_name = 'field_'. $field_name; + + $edit = array(); + // POST to the page without reloading. + $this->drupalPost(NULL, $edit, 'Save field settings'); + $this->assertRaw('Added field <em>'. $field_label .'</em>.', 'Field settings saved'); + $field_type1_url = $admin_type1_url .'/fields/'. $field_name; + $this->assertRaw($field_type1_url, 'Field displayed on overview.'); + + // Check the schema - the values should be in the per-type table. + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + $type1 => array($field_name => array('value')), + ), + )); + + + // Add a second content type. + $type2 = 'simpletest'. mt_rand(); + $type2_name = $this->randomName(10); + $edit = array( + 'type' => $type2, + 'name' => $type2_name, + ); + $this->drupalPost('admin/content/types/add', $edit, 'Save content type'); + $admin_type2_url = 'admin/content/node-type/'. $type2; + + // Add the same field to the second content type. + $edit = array( + '_add_existing_field[label]' => $field_label, + '_add_existing_field[field_name]' => $field_name, + '_add_existing_field[widget_type]' => 'text_textarea', + ); + $this->drupalPost($admin_type2_url .'/fields', $edit, 'Save'); + $this->assertRaw('These settings apply only to the <em>'. $field_label .'</em> field', 'Field settings page displayed'); + $this->assertRaw('Rows', 'Field and widget types correct.'); + $this->assertNoRaw('Change basic information', 'No basic information displayed'); + + $edit = array(); + $this->drupalPost(NULL, $edit, 'Save field settings'); + $this->assertRaw('Added field <em>'. $field_label .'</em>.', 'Field settings saved'); + $field_type2_url = $admin_type2_url .'/fields/'. $field_name; + $this->assertRaw($field_type2_url, 'Field displayed on overview.'); + + // Check that a separate table is created for the shared field, and + // that it's values are no longer in the per-type tables. + $this->assertSchemaMatchesTables(array( + 'per_field' => array( + $field_name => array($field_name => array('value')), + ), + 'per_type' => array( + $type1 => array(), + $type2 => array(), + ), + )); + + + // Chancge the basic settings for this field. + $edit = array(); + $this->drupalPost($field_type2_url, $edit, 'Change basic information'); + $this->assertRaw('Edit basic information', 'Basic information form displayed'); + + $field_label2 = $this->randomName(10); + $edit = array( + 'label' => $field_label2, + 'widget_type' => 'text_textfield', + ); + $this->drupalPost(NULL, $edit, 'Continue'); + $this->assertRaw('These settings apply only to the <em>'. $field_label2 .'</em> field', 'Label changed'); + $this->assertRaw('Size of textfield', 'Widget changed'); + + $edit = array(); + // POST to the page without reloading. + $this->drupalPost(NULL, $edit, 'Save field settings'); + $this->assertRaw('Saved field <em>'. $field_label2 .'</em>.', 'Field settings saved'); + + + // Add a group to the second content type. + $group1_name = strtolower($this->randomName(10)); + $group1_label = $this->randomName(10); + $edit = array( + '_add_new_group[label]' => $group1_label, + '_add_new_group[group_name]' => $group1_name, + ); + $this->drupalPost($admin_type2_url .'/fields', $edit, 'Save'); + $group1_name = 'group_'. $group1_name; + $this->assertRaw($admin_type2_url .'/groups/'. $group1_name, 'Group created'); + + + // Remove the field from the second type. + $edit = array(); + $this->drupalPost($field_type2_url .'/remove', $edit, 'Remove'); + $this->assertRaw('Removed field <em>'. $field_label2 .'</em> from <em>'. $type2_name .'</em>', 'Field removed'); + $this->assertNoRaw($field_type2_url, 'Field not displayed on overview.'); + + // Check the schema - the values should be in the per-type table. + $this->assertSchemaMatchesTables(array( + 'per_type' => array( + $type1 => array($field_name => array('value')), + ), + )); + + // Add a new field, an existing field, and a group in the same submit. + $field2_label = $this->randomName(10); + $field2_name = strtolower($this->randomName(10)); + $group2_label = $this->randomName(10); + $group2_name = strtolower($this->randomName(10)); + $edit = array( + '_add_new_field[label]' => $field2_label, + '_add_new_field[field_name]' => $field2_name, + '_add_new_field[type]' => 'text', + '_add_new_field[widget_type]' => 'text_textfield', + '_add_new_field[parent]' => $group1_name, + '_add_existing_field[label]' => $field_label, + '_add_existing_field[field_name]' => $field_name, + '_add_existing_field[widget_type]' => 'text_textarea', + '_add_existing_field[parent]' => '_add_new_group', + '_add_new_group[label]' => $group2_label, + '_add_new_group[group_name]' => $group2_name, + ); + $this->drupalPost($admin_type2_url .'/fields', $edit, 'Save'); + $this->assertRaw('These settings apply only to the <em>'. $field2_label .'</em> field', 'Field settings page for new field displayed'); + // Submit new field settings + $edit = array(); + $this->drupalPost(NULL, $edit, 'Save field settings'); + $this->assertRaw('Added field <em>'. $field2_label .'</em>.', 'Field settings for new field saved'); + $this->assertRaw('These settings apply only to the <em>'. $field_label .'</em> field', 'Field settings page for existing field displayed'); + // Submit existing field settings + $edit = array(); + $this->drupalPost(NULL, $edit, 'Save field settings'); + $this->assertRaw('Added field <em>'. $field_label .'</em>.', 'Field settings for existing field saved'); + $field2_name = 'field_'. $field2_name; + $field2_type2_url = $admin_type2_url .'/fields/'. $field2_name; + $this->assertRaw($field2_type2_url, 'New field displayed in overview'); + $this->assertRaw($field_type2_url, 'Existing field displayed in overview'); + $group2_name = 'group_'. $group2_name; + $this->assertRaw($admin_type2_url .'/groups/'. $group2_name, 'New group displayed in overview'); + + // Check Parenting + $groups = fieldgroup_groups($type2, FALSE, TRUE); + $this->assertTrue(isset($groups[$group1_name]['fields'][$field2_name]), 'New field in correct group'); + $this->assertTrue(isset($groups[$group2_name]['fields'][$field_name]), 'Existing field in correct group'); + $this->assertFieldByXPath('//select[@id="edit-'. strtr($field2_name, '_', '-') .'-parent"]//option[@selected]', $group1_name, 'Parenting for new field correct in overview'); + $this->assertFieldByXPath('//select[@id="edit-'. strtr($field_name, '_', '-') .'-parent"]//option[@selected]', $group2_name, 'Parenting for existing field correct in overview'); + + // Check the schema : field1 is shared, field2 is in the per-type table. + $this->assertSchemaMatchesTables(array( + 'per_field' => array( + $field_name => array($field_name => array('value')), + ), + 'per_type' => array( + $type1 => array(), + $type2 => array($field2_name => array('value')), + ), + )); + + // TODO : test validation failures... + // TODO : test ordering and extra fields... + } + + function testFieldContentUI() { + // Create a content type with a field + $type1 = 'simpletest'. mt_rand(); + $type1_obj = $this->drupalCreateContentType(array('type' => $type1)); + $admin_type1_url = 'admin/content/node-type/'. $type1; + $field_name = strtolower($this->randomName(10)); + $field_url = 'field_'. $field_name; + $field = $this->createFieldText(array('text_processing' => 1, 'multiple' => 0, 'field_name' => $field_url), $type1_obj); + + // Save a node with content in the text field + $edit = array(); + $edit['title'] = $this->randomName(20); + $edit['body'] = $this->randomName(20); + $value = $this->randomName(20); + $edit[$field_url.'[0][value]'] = $value; + $this->drupalPost('node/add/'. $type1, $edit, 'Save'); + $node = node_load(array('title' => $edit['title'])); + $this->drupalGet('node/'. $node->nid); + $this->assertText($value, 'Textfield value saved and displayed'); + + // Alter the field to have unlimited values + $edit = array(); + $edit['multiple'] = '1'; + $this->drupalPost($admin_type1_url .'/fields/'. $field_url, $edit, 'Save field settings'); + + // Save a node with content in multiple text fields + $edit = array(); + $edit['title'] = $this->randomName(20); + $edit['body'] = $this->randomName(20); + // Add more textfields (non-JS). + $this->drupalPost('node/add/'. $type1, $edit, "Add another item"); + $this->drupalPost(NULL, $edit, "Add another item"); + $value1 = $this->randomName(20); + $value2 = $this->randomName(20); + $value3 = $this->randomName(20); + $edit[$field_url.'[0][value]'] = $value1; + $edit[$field_url.'[1][value]'] = $value2; + $edit[$field_url.'[2][value]'] = $value3; + + // This will fail if we don't have at least 3 textfields. + $this->drupalPost(NULL, $edit, 'Save'); + $node = node_load(array('title' => $edit['title'])); + $this->drupalGet('node/'. $node->nid); + $this->assertText($value3, '3rd textfield value saved and displayed'); + } +} + +class ContentOptionWidgetTest extends ContentCrudTestCase { + function getInfo() { + return array( + 'name' => t('Option widgets'), + 'description' => t('Tests the optionwidgets.'), + 'group' => t('CCK'), + ); + } + + function setUp() { + parent::setUp('optionwidgets'); + $this->loginWithPermissions(); + $this->acquireContentTypes(1); + } + + // TODO: test a number field with optionwidgets stores 0 correctly ? + // TODO: test the case where aliases and values overlap ? (http://drupal.org/node/281749) + // TODO: test noderef select widget... + + /** + * On/Off Checkbox, not required: + * - Create a node with the value checked. + * - FAILS: Edit the node and uncheck the value. + * + * On/Off Checkbox, required: + * - TODO: what behavior do we want ? + */ + function testOnOffCheckbox() { + $type = $this->content_types[0]; + $type_url = str_replace('_', '-', $type->type); + + // Create the field. + $on_text = $this->randomName(5); + $on_value = $this->randomName(5); + $off_text = $on_text. '_off'; + $off_value = $on_value. '_off'; + + $settings = array( + 'type' => 'text', + 'widget_type' => 'optionwidgets_onoff', + 'allowed_values' => "$off_value|$off_text\r\n$on_value|$on_text", + ); + $field = $this->createField($settings, 0); + $field_name = $field['field_name']; + + // Create a node with the checkbox on. + $edit = array( + 'title' => $this->randomName(20), + 'body' => $this->randomName(20), + $field_name.'[value]' => $on_value, + ); + $this->drupalPost('node/add/'. $type_url, $edit, 'Save'); + $node = node_load(array('title' => $edit['title'])); + $this->assertEqual($node->{$field_name}[0]['value'], $on_value, 'Checkbox: checked (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertText($on_text, 'Checkbox: checked (displayed)'); + + // Edit the node and uncheck the box. + $edit = array( + $field_name.'[value]' => FALSE, + ); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertEqual($node->{$field_name}[0]['value'], $off_value, 'Checkbox: unchecked (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertText($off_text, 'Checkbox: unchecked (displayed)'); + } + + /** + * Single select, not required: + * - TODO: check there's a 'none' choice in the form. + * - Create a node with one value selected. + * - Edit the node and unselect the value (selecting '- None -'). + * + * Single select, required: + * - TODO: check there's no 'none' choice in the form. + * + * Multiple select, not required: + * - TODO: check there's a 'none' choice in the form. + * - Edit the node and select multiple values. + * - Edit the node and unselect one value. + * - Edit the node and unselect the values (selecting '- None -'). + * - Edit the node and unselect the values (selecting nothing). + * + * Multiple select, required: + * - TODO: check there's no 'none' choice in the form. + * - Check the form doesn't submit when nothing is selected. + */ + function testSelect() { + $type = $this->content_types[0]; + $type_url = str_replace('_', '-', $type->type); + + // Create the field - start with 'single'. + $value1 = $this->randomName(5); + $value1_alias = $value1 .'_alias'; + $value2 = $this->randomName(5); + $value2_alias = $value2 .'_alias'; + + $settings = array( + 'type' => 'text', + 'widget_type' => 'optionwidgets_select', + 'allowed_values' => "$value1|$value1_alias\r\n$value2|$value2_alias", + ); + $field = $this->createField($settings, 0); + $field_name = $field['field_name']; + + // Create a node with one value selected + $edit = array( + 'title' => $this->randomName(20), + 'body' => $this->randomName(20), + ); + $edit[$field_name.'[value]'] = $value1; + $this->drupalPost('node/add/'. $type_url, $edit, 'Save'); + $node = node_load(array('title' => $edit['title'])); + $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Select: selected (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertText($value1_alias, 'Select: selected (displayed)'); + + // Edit the node and unselect the value (selecting '- None -'). + $edit = array( + $field_name.'[value]' => '', + ); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Select: unselected (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertNoText($value1_alias, 'Select: unselected (displayed)'); + + // Change to a multiple field + $field = $this->updateField(array('multiple' => '1', 'required' => '0')); + + // Edit the node and select multiple values. + $edit = array( + $field_name.'[value][]' => array($value1 => $value1, $value2 => $value2), + ); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Multiple Select: selected 1 (saved)'); + $this->assertEqual($node->{$field_name}[1]['value'], $value2, 'Multiple Select: selected 2 (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertText($value1_alias, 'Multiple Select: selected 1 (displayed)'); + $this->assertText($value2_alias, 'Multiple Select: selected 2 (displayed)'); + + // Edit the node and unselect one value. + $edit = array( + $field_name.'[value][]' => array($value1 => $value1), + ); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Multiple Select: selected 1 (saved)'); + $this->assertTrue(!isset($node->{$field_name}[1]), 'Multiple Select: unselected 2 (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertText($value1_alias, 'Multiple Select: selected 1 (displayed)'); + $this->assertNoText($value2_alias, 'Multiple Select: unselected 2 (displayed)'); + + // Edit the node and unselect the values (selecting '- None -'). + $edit = array( + $field_name.'[value][]' => array('' => ''), + ); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Multiple Select: unselected 1 ("-none-" selected) (saved)'); + $this->assertTrue(!isset($node->{$field_name}[1]), 'Multiple Select: unselected 2 ("-none-" selected) (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertNoText($value1_alias, 'Multiple Select: unselected 1 ("-none-" selected) (displayed)'); + $this->assertNoText($value2_alias, 'Multiple Select: unselected 2 ("-none-" selected) (displayed)'); + + // Edit the node and unselect the values (selecting nothing). + // We first need to put values back in (no test needed). + $edit = array(); + $edit[$field_name.'[value][]'] = array($value1 => FALSE, $value2 => FALSE); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $edit = array(); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Multiple Select: unselected 1 (no selection) (saved)'); + $this->assertTrue(!isset($node->{$field_name}[1]), 'Multiple Select: unselected 2 (no selection) (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertNoText($value1_alias, 'Multiple Select: unselected 1 (no selection) (displayed)'); + $this->assertNoText($value2_alias, 'Multiple Select: unselected 2 (no selection) (displayed)'); + + // Change the field to 'required'. + $field = $this->updateField(array('required' => '1')); + + // Check the form doesn't submit when nothing is selected. + $edit = array(); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Multiple Select: "required" property is respected'); + + $edit = array( + 'title' => $this->randomName(20), + 'body' => $this->randomName(20), + ); + $this->drupalPost('node/add/'. $type_url, $edit, 'Save'); + $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Multiple Select: "required" property is respected'); + + } + + /** + * Single (radios), not required: + * - TODO: check there's a 'none' choice in the form. + * - Create a node with one value selected. + * - Edit the node and unselect the value (selecting '- None -'). + * + * Single (radios), required: + * - TODO: check there's no 'none' choice in the form. + * - Check the form doesn't submit when nothing is selected. + */ + function testRadios() { + $type = $this->content_types[0]; + $type_url = str_replace('_', '-', $type->type); + + // Create the field - 'single' (radios). + $value1 = $this->randomName(5); + $value1_alias = $value1 .'_alias'; + $value2 = $this->randomName(5); + $value2_alias = $value2 .'_alias'; + $settings = array( + 'type' => 'text', + 'widget_type' => 'optionwidgets_buttons', + 'allowed_values' => "$value1|$value1_alias\r\n$value2|$value2_alias", + ); + $field = $this->createField($settings, 0); + $field_name = $field['field_name']; + + // Create a node with one value selected + $edit = array(); + $edit['title'] = $this->randomName(20); + $edit['body'] = $this->randomName(20); + $edit[$field_name.'[value]'] = $value1; + $this->drupalPost('node/add/'. $type_url, $edit, 'Save'); + $node = node_load(array('title' => $edit['title'])); + $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Radios: checked (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertText($value1_alias, 'Radios: checked (displayed)'); + + // Edit the node and unselect the value (selecting '- None -'). + $edit = array(); + $edit[$field_name.'[value]'] = ''; + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Radios: unchecked (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertNoText($value1_alias, 'Radios: unchecked (displayed)'); + + // Change field to required. + $field = $this->updateField(array('required' => '1')); + + // Check the form doesn't submit when nothing is selected. + // Doing this on the pre-filled node doesn't take, so we test that on a new node. + $edit = array(); + $edit['title'] = $this->randomName(20); + $edit['body'] = $this->randomName(20); + $this->drupalPost('node/add/'. $type_url, $edit, 'Save'); + $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Radios: "required" property is respected'); + } + + /** + * Multiple (checkboxes), not required: + * - TODO: check there's no 'none' choice in the form. + * - Create a node with two values. + * - Edit the node and select only one value. + * - Edit the node and unselect the values (selecting nothing). + * + * Multiple (checkboxes), required: + * - TODO: check there's no 'none' choice in the form. + * - Check the form doesn't submit when nothing is selected. + */ + function testChecboxes() { + $type = $this->content_types[0]; + $type_url = str_replace('_', '-', $type->type); + + // Create the field - 'multiple' (checkboxes). + $value1 = $this->randomName(5); + $value1_alias = $value1 .'_alias'; + $value2 = $this->randomName(5); + $value2_alias = $value2 .'_alias'; + $settings = array( + 'type' => 'text', + 'multiple' => '1', + 'widget_type' => 'optionwidgets_buttons', + 'allowed_values' => "$value1|$value1_alias\r\n$value2|$value2_alias", + ); + $field = $this->createField($settings, 0); + $field_name = $field['field_name']; + + // Create a node with two values selected + $edit = array( + 'title' => $this->randomName(20), + 'body' => $this->randomName(20), + $field_name.'[value]['. $value1 .']' => $value1, + $field_name.'[value]['. $value2 .']' => $value2, + ); + $this->drupalPost('node/add/'. $type_url, $edit, 'Save'); + $node = node_load(array('title' => $edit['title'])); + $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Checkboxes: selected 1 (saved)'); + $this->assertEqual($node->{$field_name}[1]['value'], $value2, 'Checkboxes: selected 2 (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertText($value1_alias, 'Checkboxes: selected 1 (displayed)'); + $this->assertText($value2_alias, 'Checkboxes: selected 2 (displayed)'); + + // Edit the node and unselect the values (selecting nothing - + // there is no 'none' choice for checkboxes). + $edit = array( + $field_name.'[value]['. $value1 .']' => $value1, + $field_name.'[value]['. $value2 .']' => FALSE, + ); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Checkboxes: selected 1 (saved)'); + $this->assertTrue(!isset($node->{$field_name}[1]), 'Checkboxes: unselected 2 (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertText($value1_alias, 'Checkboxes: selected 1 (displayed)'); + $this->assertNoText($value2_alias, 'Checkboxes: unselected 2 (displayed)'); + + // Edit the node and unselect the values (selecting nothing - + // there is no 'none' choice for checkboxes). + $edit = array( + $field_name.'[value]['. $value1 .']' => FALSE, + $field_name.'[value]['. $value2 .']' => FALSE, + ); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $node = node_load($node->nid, NULL, TRUE); + $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Checkboxes: unselected 1 (no selection) (saved)'); + $this->assertTrue(!isset($node->{$field_name}[1]), 'Checkboxes: unselected 2 (no selection) (saved)'); + $this->drupalGet('node/'. $node->nid); + $this->assertNoText($value1_alias, 'Checkboxes: unselected 1 (no selection) (displayed)'); + $this->assertNoText($value2_alias, 'Checkboxes: unselected 2 (no selection) (displayed)'); + + // Change field to required. + $field = $this->updateField(array('required' => '1')); + + // Check the form doesn't submit when nothing is selected. + $edit = array( + $field_name.'[value]['. $value1 .']' => FALSE, + $field_name.'[value]['. $value2 .']' => FALSE, + ); + $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save'); + $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Checkboxes: "required" property is respected'); + + $edit = array(); + $edit['title'] = $this->randomName(20); + $edit['body'] = $this->randomName(20); + $this->drupalPost('node/add/'. $type_url, $edit, 'Save'); + $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Checkboxes: "required" property is respected'); + } + +} + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-display-overview-form.tpl.php b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-display-overview-form.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..3658ac5768f32fbd7926a52ff16807e9cccedb96 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-display-overview-form.tpl.php @@ -0,0 +1,40 @@ +<?php +// $Id$ +?> +<div> + <?php print $help; ?> +</div> +<?php if ($rows): ?> + <table id="content-display-overview" class="sticky-enabled"> + <thead> + <tr> + <th><?php print t('Field'); ?></th> + <?php if ($basic): ?> + <th><?php print t('Label'); ?></th> + <?php endif; ?> + <?php foreach ($contexts as $key => $value): ?> + <th><?php print $value['title']; ?></th> + <th><?php print t('Exclude'); ?></th> + <?php endforeach; ?> + </tr> + </thead> + <tbody> + <?php + $count = 0; + foreach ($rows as $row): ?> + <tr class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?>"> + <td><?php print $row->indentation; ?><span class="<?php print $row->label_class; ?>"><?php print $row->human_name; ?></span></td> + <?php if ($basic): ?> + <td><?php print $row->label; ?></td> + <?php endif; ?> + <?php foreach ($contexts as $context => $title): ?> + <td><?php print $row->{$context}->format; ?></td> + <td><?php print $row->{$context}->exclude; ?></td> + <?php endforeach; ?> + </tr> + <?php $count++; + endforeach; ?> + </tbody> + </table> + <?php print $submit; ?> +<?php endif; ?> diff --git a/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-field-overview-form.tpl.php b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-field-overview-form.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..0eab64c58ac8ba1df1902966bda70c2dae06778e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-field-overview-form.tpl.php @@ -0,0 +1,102 @@ +<?php +// $Id$ +?> +<div> + <?php print $help; ?> +</div> +<table id="content-field-overview" class="sticky-enabled"> + <thead> + <tr> + <th><?php print t('Label'); ?></th> + <th><?php print t('Weight'); ?></th> + <th><?php print t('Name'); ?></th> + <th><?php print t('Type'); ?></th> + <th><?php print t('Operations'); ?></th> + </tr> + </thead> + <tbody> + <?php + $count = 0; + foreach ($rows as $row): ?> + <tr class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?> <?php print $row->class ?>"> + <?php + switch ($row->row_type): + case 'field': ?> + <td> + <?php print $row->indentation; ?> + <span class="<?php print $row->label_class; ?>"><?php print $row->label; ?></span> + </td> + <td><?php print $row->weight . $row->parent . $row->hidden_name; ?></td> + <td><?php print $row->field_name; ?></td> + <td><?php print $row->type; ?></td> + <td><?php print $row->configure; ?> <?php print $row->remove; ?></td> + <?php break; + case 'group': ?> + <td> + <?php print $row->indentation; ?> + <span class="<?php print $row->label_class; ?>"><?php print $row->label; ?></span> + </td> + <td><?php print $row->weight . $row->parent . $row->hidden_name; ?></td> + <td><?php print $row->group_name; ?></td> + <td><?php print $row->group_type; ?></td> + <td><?php print $row->configure; ?> <?php print $row->remove; ?></td> + <?php break; + case 'extra': ?> + <td> + <?php print $row->indentation; ?> + <span class="<?php print $row->label_class; ?>"><?php print $row->label; ?></span> + </td> + <td><?php print $row->weight . $row->parent . $row->hidden_name; ?></td> + <td colspan="2"><?php print $row->description; ?></td> + <td><?php print $row->configure; ?> <?php print $row->remove; ?></td> + <?php break; + case 'separator': ?> + <td colspan="5" class="region"><?php print t('Add'); ?></td> + <?php break; + case 'add_new_field': ?> + <td> + <?php print $row->indentation; ?> + <div class="<?php print $row->label_class; ?>"> + <div class="content-new"><?php print theme('advanced_help_topic', 'content', 'add-new-field') . t('New field'); ?></div> + <?php print $row->label; ?> + </div> + </td> + <td><div class="content-new"> </div><?php print $row->weight . $row->parent . $row->hidden_name; ?></td> + <td><div class="content-new"> </div><?php print $row->field_name; ?></td> + <td><div class="content-new"> </div><?php print $row->type; ?></td> + <td><div class="content-new"> </div><?php print $row->widget_type; ?></td> + <?php break; + case 'add_existing_field': ?> + <td> + <?php print $row->indentation; ?> + <div class="<?php print $row->label_class; ?>"> + <div class="content-new"><?php print theme('advanced_help_topic', 'content', 'add-existing-field') . t('Existing field'); ?></div> + <?php print $row->label; ?> + </div> + </td> + <td><div class="content-new"> </div><?php print $row->weight . $row->parent . $row->hidden_name; ?></td> + <td colspan="2"><div class="content-new"> </div><?php print $row->field_name; ?></td> + <td><div class="content-new"> </div><?php print $row->widget_type; ?></td> + <?php break; + case 'add_new_group': ?> + <td> + <?php print $row->indentation; ?> + <div class="<?php print $row->label_class; ?>"> + <div class="content-new"><?php print theme('advanced_help_topic', 'content', 'add-new-group') . t('New group'); ?></div> + <?php print $row->label; ?> + </div> + </td> + <td><div class="content-new"> </div><?php print $row->weight . $row->parent . $row->hidden_name; ?></td> + <td><div class="content-new"> </div><?php print $row->group_name; ?></td> + <td><div class="content-new"> </div><?php print $row->group_type; ?></td> + <td><div class="content-new"> </div><?php print $row->group_option; ?></td> + <?php break; + endswitch; ?> + </tr> + <?php $count++; + endforeach; ?> + </tbody> +</table> + +<?php print $submit; ?> + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/theme/content-field.tpl.php b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-field.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..e3538e44fee27b0221f77ac8e01f802bc53b8503 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-field.tpl.php @@ -0,0 +1,49 @@ +<?php +// $Id$ + +/** + * @file content-field.tpl.php + * Default theme implementation to display the value of a field. + * + * Available variables: + * - $node: The node object. + * - $field: The field array. + * - $items: An array of values for each item in the field array. + * - $teaser: Whether this is displayed as a teaser. + * - $page: Whether this is displayed as a page. + * - $field_name: The field name. + * - $field_type: The field type. + * - $field_name_css: The css-compatible field name. + * - $field_type_css: The css-compatible field type. + * - $label: The item label. + * - $label_display: Position of label display, inline, above, or hidden. + * - $field_empty: Whether the field has any valid value. + * + * Each $item in $items contains: + * - 'view' - the themed view for that item + * + * @see template_preprocess_content_field() + */ +?> +<?php if (!$field_empty) : ?> +<div class="field field-type-<?php print $field_type_css ?> field-<?php print $field_name_css ?>"> + <?php if ($label_display == 'above') : ?> + <div class="field-label"><?php print t($label) ?>: </div> + <?php endif;?> + <div class="field-items"> + <?php $count = 1; + foreach ($items as $delta => $item) : + if (!$item['empty']) : ?> + <div class="field-item <?php print ($count % 2 ? 'odd' : 'even') ?>"> + <?php if ($label_display == 'inline') { ?> + <div class="field-label-inline<?php print($delta ? '' : '-first')?>"> + <?php print t($label) ?>: </div> + <?php } ?> + <?php print $item['view'] ?> + </div> + <?php $count++; + endif; + endforeach;?> + </div> +</div> +<?php endif; ?> diff --git a/drupal/sites/default/boinc/modules/contrib/cck/theme/content-module-rtl.css b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-module-rtl.css new file mode 100644 index 0000000000000000000000000000000000000000..f1236e1801bd9521641c5a3868b2059f35de7ddb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-module-rtl.css @@ -0,0 +1,22 @@ +/* $Id$ */ + +/* Node form display */ +.node-form .content-multiple-table td.content-multiple-drag { + padding-left:0; + padding-right:0.5em; +} +.node-form .content-multiple-table td.content-multiple-drag a.tabledrag-handle{ + padding-left:.5em; +} + +/* 'Manage fields' overview */ +#content-field-overview-form .advanced-help-link, +#content-display-overview-form .advanced-help-link { + margin: 4px 0 0 4px; +} + +table#content-field-overview .label-add-new-field, +table#content-field-overview .label-add-existing-field, +table#content-field-overview .label-add-new-group { + float: right; +} diff --git a/drupal/sites/default/boinc/modules/contrib/cck/theme/content-module.css b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-module.css new file mode 100644 index 0000000000000000000000000000000000000000..8888ae5ce4c36b978189670ef3be788826fdf8f3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-module.css @@ -0,0 +1,97 @@ +/* $Id$ */ + +/* Node display */ +.field .field-label, +.field .field-label-inline, +.field .field-label-inline-first { + font-weight:bold; +} +.field .field-label-inline, +.field .field-label-inline-first { + display:inline; +} +.field .field-label-inline { + visibility:hidden; +} + +/* Node form display */ +.node-form .content-multiple-table td.content-multiple-drag { + width:30px; + padding-right:0;/*LTR*/ +} +.node-form .content-multiple-table td.content-multiple-drag a.tabledrag-handle{ + padding-right:.5em;/*LTR*/ +} + +.node-form .content-add-more .form-submit{ + margin:0; +} + +.node-form .number { + display:inline; + width:auto; +} +.node-form .text { + width:auto; +} + +/* CSS overrides for Views-based autocomplete results. + - #autocomplete uses "white-space:pre", which is no good with + Views' template-based rendering + - Field titles are rendered with <label> in default templates, + but we don't want the 'form' styling it gets under .form-item +*/ +.form-item #autocomplete .reference-autocomplete { + white-space:normal; +} + +.form-item #autocomplete .reference-autocomplete label { + display:inline; + font-weight:normal; +} + +/* 'Manage fields' overview */ +#content-field-overview-form .advanced-help-link, +#content-display-overview-form .advanced-help-link { + margin: 4px 4px 0 0;/*LTR*/ +} +#content-field-overview-form .label-group, +#content-display-overview-form .label-group, +#content-copy-export-form .label-group { + font-weight: bold; +} +table#content-field-overview .label-add-new-field, +table#content-field-overview .label-add-existing-field, +table#content-field-overview .label-add-new-group { + float: left;/*LTR*/ +} +table#content-field-overview tr.content-add-new .tabledrag-changed { + display: none; +} +table#content-field-overview tr.content-add-new .description { + margin-bottom: 0; +} +table#content-field-overview .content-new { + font-weight: bold; + padding-bottom: .5em; +} + +/* 'Advanced help' pages */ +.advanced-help-topic h3, +.advanced-help-topic h4, +.advanced-help-topic h5, +.advanced-help-topic h6 { + margin:1em 0 .5em 0; +} +.advanced-help-topic dd { + margin-bottom: .5em; +} +.advanced-help-topic span.code { + background-color:#EDF1F3; + font-family:"Bitstream Vera Sans Mono",Monaco,"Lucida Console",monospace; + font-size:0.9em; + padding:1px; +} +.advanced-help-topic .content-border { + border:1px solid #AAA +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/theme/theme.inc b/drupal/sites/default/boinc/modules/contrib/cck/theme/theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..517a25faf6b082224d7ab35fdd98d4559712f419 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/theme/theme.inc @@ -0,0 +1,145 @@ +<?php +// $Id$ + +/** + * @file + * Theme preprocess function for content-admin-field-overview-form.tpl.php. + */ +function template_preprocess_content_field_overview_form(&$vars) { + $form = &$vars['form']; + + $vars['help'] = theme('advanced_help_topic', 'content', 'manage-fields') . t('Add fields and groups to the content type, and arrange them on content display and input forms.'); + if (module_exists('fieldgroup')) { + $vars['help'] .= '<br/>'. t('You can add a field to a group by dragging it below and to the right of the group.'); + } + if (!module_exists('advanced_help')) { + $vars['help'] .= '<br/>' . t('Note: Installing the <a href="!adv_help">Advanced help</a> module will let you access more and better help.', array('!adv_help' => 'http://drupal.org/project/advanced_help')); + } + + $order = _content_overview_order($form, $form['#field_rows'], $form['#group_rows']); + $rows = array(); + + // Identify the 'new item' keys in the form, they look like + // _add_new_field, add_new_group. + $keys = array_keys($form); + $add_rows = array(); + foreach ($keys as $key) { + if (substr($key, 0, 4) == '_add') { + $add_rows[] = $key; + } + } + while ($order) { + $key = reset($order); + $element = &$form[$key]; + + // Only display the 'Add' separator if the 'add' rows are still + // at the end of the table. + if (!isset($added_separator)) { + $remaining_rows = array_diff($order, $add_rows); + if (empty($remaining_rows) && empty($element['#depth'])) { + $row = new stdClass(); + $row->row_type = 'separator'; + $row->class = 'tabledrag-leaf region'; + $rows[] = $row; + $added_separator = TRUE; + } + } + + $row = new stdClass(); + + // Add target classes for the tabledrag behavior. + $element['weight']['#attributes']['class'] = 'field-weight'; + $element['parent']['#attributes']['class'] = 'group-parent'; + $element['hidden_name']['#attributes']['class'] = 'field-name'; + // Add target classes for the update selects behavior. + switch ($element['#row_type']) { + case 'add_new_field': + $element['type']['#attributes']['class'] = 'content-field-type-select'; + $element['widget_type']['#attributes']['class'] = 'content-widget-type-select'; + break; + case 'add_existing_field': + $element['field_name']['#attributes']['class'] = 'content-field-select'; + $element['widget_type']['#attributes']['class'] = 'content-widget-type-select'; + $element['label']['#attributes']['class'] = 'content-label-textfield'; + break; + } + foreach (element_children($element) as $child) { + $row->{$child} = drupal_render($element[$child]); + } + $row->label_class = 'label-'. strtr($element['#row_type'], '_', '-'); + $row->row_type = $element['#row_type']; + $row->indentation = theme('indentation', isset($element['#depth']) ? $element['#depth'] : 0); + $row->class = 'draggable'; + $row->class .= isset($element['#disabled_row']) ? ' menu-disabled' : ''; + $row->class .= isset($element['#add_new']) ? ' content-add-new' : ''; + $row->class .= isset($element['#leaf']) ? ' tabledrag-leaf' : ''; + $row->class .= isset($element['#root']) ? ' tabledrag-root' : ''; + + $rows[] = $row; + array_shift($order); + } + $vars['rows'] = $rows; + $vars['submit'] = drupal_render($form); + + // Add tabledrag behavior. +// drupal_add_tabledrag('content-field-overview', 'match', 'parent', 'group-parent', 'group-parent', 'field-name', FALSE, 1); + drupal_add_tabledrag('content-field-overview', 'match', 'parent', 'group-parent', 'group-parent', 'field-name', TRUE, 1); +// drupal_add_tabledrag('content-field-overview', 'order', 'sibling', 'field-weight', NULL, NULL, FALSE); + drupal_add_tabledrag('content-field-overview', 'order', 'sibling', 'field-weight'); + + // Add settings for the update selects behavior. + $js_fields = array(); + foreach (array_keys(content_existing_field_options($form['#type_name'])) as $field_name) { + $field = content_fields($field_name); + $js_fields[$field_name] = array('label' => $field['widget']['label'], 'type' => $field['type'], 'widget' => $field['widget']['type']); + } + drupal_add_js(array('contentWidgetTypes' => content_widget_type_options(), 'contentFields' => $js_fields), 'setting'); + drupal_add_js(drupal_get_path('module', 'content') .'/content.js'); +} + +/** + * Theme preprocess function for content-admin-display-overview-form.tpl.php. + */ +function template_preprocess_content_display_overview_form(&$vars) { + $form = &$vars['form']; + + $contexts_selector = $form['#contexts']; + $vars['basic'] = $contexts_selector == 'basic'; + $vars['contexts'] = content_build_modes($contexts_selector); + + if ($contexts_selector == 'basic') { + $help = t("Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode."); + } + else { + $help = t("Configure how this content type's fields should be displayed when it's rendered in the following contexts."); + } + $help .= ' '. t("Use the 'Exclude' checkbox to exclude an item from the !content value passed to the node template.", array('!content' => '$content')); + $vars['help'] = $help; + + $order = _content_overview_order($form, $form['#fields'], $form['#groups']); + if (empty($order)) { + $vars['rows'] = array(); + $vars['submit'] = ''; + return; + } + + $rows = array(); + foreach ($order as $key) { + $element = &$form[$key]; + $row = new stdClass(); + foreach (element_children($element) as $child) { + if (!array_key_exists('exclude', $element[$child])) { + $row->{$child} = drupal_render($element[$child]); + } + else { + $row->{$child}->format = drupal_render($element[$child]['format']); + $row->{$child}->exclude = drupal_render($element[$child]['exclude']); + } + } + $row->label_class = in_array($key, $form['#groups']) ? 'label-group' : 'label-field'; + $row->indentation = theme('indentation', isset($element['#depth']) ? $element['#depth'] : 0); + $rows[] = $row; + } + $vars['rows'] = $rows; + $vars['submit'] = drupal_render($form); +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/content.de.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/content.de.po new file mode 100644 index 0000000000000000000000000000000000000000..897b2aaead07b6579d992afdafbbbf4d3eaa235d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/content.de.po @@ -0,0 +1,245 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:14+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: content.module:21 +msgid "The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default \"Title\" and \"Body\" may be added. CCK features are accessible through tabs on the <a href=\"@content-types\">content types administration page</a>. (See the <a href=\"@node-help\">node module help page</a> for more information about content types.)" +msgstr "Das Content-Modul ist eine erforderliche Komponente des Content Construction Kit (CCK) und ermöglicht Administratoren benutzerdefinierte Felder mit Inhaltstypen zu verknüpfen. In Drupal werden Inhaltstypen dazu verwendet, die Eigenschaften eines Beitrags inklusive dem Titel und der Beschreibung von Feldern festzulegen, die auf deren „Hinzufügen“ und „Bearbeiten“-Seiten angezeigt werden. Die Verwendung des Content-Moduls (und der anderen in CCK enthaltenen Hilfsmodule) können benutzerdefinierte Felder über die standardmäßigen „Titel“ und „Textkörper“-Felder hinaus hinzugefügt werden. CCK-Funktionen sind verfügbar über Tabulatoren auf der <a href=\"@content-types\">Verwaltungsseite für Inhaltstypen</a>. (Nähere Informationen bezüglich Inhaltstypen gibt es auf der <a href=\"@node-help\">Hilfeseite des Inhalts-Moduls</a>.)" + +#: content.module:22 +msgid "When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a \"person\" may have multiple e-mail addresses) or a single value (i.e., an \"employee\" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules." +msgstr "Beim Hinzufügen eines benutzerdefiniertes Feldes zu einem Inhaltstyp, wird der Typ festgelegt (ob dieser Text enthält, Zahlen oder Referenzen auf andere Objekte) und wie dieser Angezeigt wird (entweder als Textfeld oder -bereich, Auswahlfeld, Ankreuzfeld, Auswahlknopf oder Autovervollständigungsfeld). Ein Feld kann mehrere Werte enthalten (d.h., eine „Person“ kann mehrere E-Mail-Adressen haben) oder ein einfacher Wert (d.h., ein „Mitarbeiter“ hat eine Mitarbeiteridentifikationsnummer). Sollten Felder hinzugefügt und bearbeitet werden, passt CCK automatisch die Datenbank an die erforderliche Struktur an. CCK ermöglich auch eine Anzahl von anderen Funktionen, inklusive intelligenten Caching für benutzerdefinierte Daten, eine Import- und Export-Möglichkeit von festgelegten Inhaltstypen und die Integration von weiteren Modulen." + +#: content.module:23 +msgid "Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href=\"@modules\">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:" +msgstr "Benutzerdefinierte Feldtypen werden von einer Reihe an optionalen Modulen zu Verfügung gestellt, die in CCK enthalten sind (jedes Modul stellt einen anderen Typ zu Verfügung). Die <a href=\"@modules\">Modulseite</a> ermöglicht die Aktivierung oder Deaktivierung von CCK-Komponenten. Eine standardmäßige Installation von CCK enthält:" + +#: content.module:25 +msgid "<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available." +msgstr "<em>Zahl</em>, welches numerische Feldtypen in Form von Ganzzahl, Dezimalzahl oder Fließkommazahl hinzufügt. Die zulässigen Eingaben oder ein zulässiger Bereich von Werten kann festgelegt werden. Eine Auswahl von Standardformaten für die Anzeige numerischer Daten ist vorhanden." + +#: content.module:26 +msgid "<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values." +msgstr "<em>Text</em>, welches Textfeldtypen hinzufügt. Ein Textfeld kann nur Klartext oder optional die Eingabefilterformate von Drupal verwenden, um Texteingaben sicher zu verwalten. Texteingabefelder können eine einfache Zeile (Textfeld), mehrere Zeilen (Textbereich) oder für größere Eingabekontrolle aus einem Auswahlfeld, Ankreuzfeld oder Auswahlknopf bestehen. Auf Wunsch kann CCK die Eingaben gegen einer Reihe von zulässigen Werten überprüfen." + +#: content.module:27 +msgid "<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple \"employee\" nodes may contain a <em>nodereference</em> field linking to an \"employer\" node)." +msgstr "<em>Beitragsreferenz</em>, welches benutzerdefinierte Referenzen zwischen Drupal-Beiträgen erstellt. Durch Hinzufügen eines <em>Beitragsreferenz</em>-Feldes und zwei unterschiedlichen Inhaltstypen können Beispielsweise auf einfachem Weg komplexe Übergeordnet/Untergeordnet-Beziehungen zwischen Daten erstellt werden (mehrere „Mitarbeiterbeiträge“ können ein <em>Beitragsreferenz</em>-Feld enthalten, das auf einen „Arbeitgeberbeitrag“ verweist)." + +#: content.module:28 +msgid "<em>userreference</em>, which creates custom references to your sites' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site's users and posts. To track user involvement in a post beyond Drupal's standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named \"Edited by\" to a content type to store a link to an editor's user account page." +msgstr "<em>Benutzerreferenz</em>, welche benutzerdefinierte Referenzen zu den Benutzerkonten der Website erstellt. Durch Hinzufügen eines <em>Benutzerreferenz</em>-Feldes können komplexe Beziehungen zwischen den Benutzern der Website und Beiträgen erstellt werden. Um an einem Beitrag beteiligte Benutzer, über das standardmäßige Drupal-Feld <em>geschrieben von</em> hinaus zu tracken, kann Beispielsweise ein <em>Benutzerreferenz</em>-Feld mit dem Namen „Bearbeitet von“ zu einem Inhaltstypen hinzugefügt werden, um einen Verweis auf die Benutzerkontoseite des Bearbeiters zu speichern." + +#: content.module:29 +msgid "<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module." +msgstr "<em>Feldgruppe</em>, welches zusammenklappbare Feldgruppen erstellt, die eine Gruppe von zugehörigen Feldern enthält. Eine Feldgruppe kann standardmäßig offen oder geschlossen sein. Die Reihenfolge der Feldgruppe und die Reihenfolge der Felder innerhalb der Feldgruppe, wird mit einer vom Content-Modul zu Verfügung gestellten Drag-und-Drop-Oberfläche verwaltet." + +#: content.module:31 +msgid "For more information, see the online handbook entry for <a href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK project page</a>." +msgstr "Nähere Informationen bezüglich der Konfiguration und Anpassung gibt es auf der Handbuch-Seite zum <a href=\"@handbook-cck\">CCK-Modul</a> oder auf der <a href=\"@project-cck\">CCK-Projektseite</a>." + +#: content.module:492 +msgid "This field is required." +msgstr "Dieses Feld wird benötigt." + +#: content.module:496 +msgid "!title: !required" +msgstr "!title: !required" + +#: content.module:1854 +msgid "Basic" +msgstr "Basis" + +#: content.module:1867;1870 +msgid "RSS" +msgstr "RSS" + +#: content.module:1880 +msgid "Search" +msgstr "Suchen" + +#: content.module:1883 +msgid "Search Index" +msgstr "Suchindex" + +#: content.module:1887 +msgid "Search Result" +msgstr "Suchergebnis" + +#: content.module:1897;1900 +#, fuzzy +msgid "Print" +msgstr "Drucken" + +#: content.module:2348;2355 +msgid "Node module form." +msgstr "Formular des Beitrag-Moduls." + +#: content.module:2362 +msgid "Language" +msgstr "Sprache" + +#: content.module:2363 +msgid "Locale module form." +msgstr "Formular des Locale-Moduls." + +#: content.module:2369 +msgid "Menu settings" +msgstr "Menüeinstellungen" + +#: content.module:2370 +msgid "Menu module form." +msgstr "Formular des Menü-Moduls." + +#: content.module:2376 +msgid "Taxonomy" +msgstr "Taxonomie" + +#: content.module:2377 +msgid "Taxonomy module form." +msgstr "Formular des Taxonomie-Moduls." + +#: content.module:2383 +msgid "Book" +msgstr "Buch" + +#: content.module:2384 +msgid "Book module form." +msgstr "Formular des Buch-Moduls." + +#: content.module:2390 +msgid "Poll title" +msgstr "Umfragetitel" + +#: content.module:2391 +msgid "Poll module title." +msgstr "Umfragemodultitel" + +#: content.module:2395 +msgid "Poll choices" +msgstr "" + +#: content.module:2396 +msgid "Poll module choices." +msgstr "" + +#: content.module:2400 +msgid "Poll settings" +msgstr "Umfrageeinstellungen" + +#: content.module:2401 +msgid "Poll module settings." +msgstr "Umfragemoduleinstellungen" + +#: content.module:2407 +msgid "File attachments" +msgstr "Dateianhänge" + +#: content.module:2408 +msgid "Upload module form." +msgstr "Formular des Upload-Moduls." + +#: content.module:595 +msgid "Updating field type %type with module %module." +msgstr "Feldtyp %type wird mit Modul %module aktualisiert." + +#: content.module:602 +msgid "Updating widget type %type with module %module." +msgstr "Widget %type wird mit Modul %module aktualisiert." + +#: content.module:60 +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "PHP-Eingabe für Feldeinstellungen verwenden (Gefährlich - mit Vorsicht zu gewähren)" + +#: content.module:79 +msgid "Fields" +msgstr "Felder" + +#: content.module:101 +msgid "Manage fields" +msgstr "Felder verwalten" + +#: content.module:110 +msgid "Display fields" +msgstr "Felder anzeigen" + +#: content.module:141 +msgid "Remove field" +msgstr "Feld löschen" + +#: content.install:236 +msgid "Updates for CCK-related modules are not run until the modules are enabled on the <a href=\"@admin-modules-path\">administer modules page</a>. When you enable them, you'll need to return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Aktualisierungen für CCK verwandte Module werden nicht ausgeführt, bis die Module auf der <a href=\"@admin-modules-path\">Verwaltungsseite für Module</a> aktiviert wurden. Sobald diese aktiviert werden, müssen die ausstehenden Aktualisierungen auf der <a href=\"@update-php\">update.php</a>-Seite ausgeführt werden." + +#: content.install:239 +msgid "!module.module has updates but cannot be updated because content.module is not enabled.<br />If and when content.module is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "Für !module.module liegen Aktualisierungen vor. Dieses kann aber nicht aktualisiert werden, da das content.module nicht aktiviert ist.<br />Wenn das content.module aktiviert wird, muss das Aktualisierungsskript noch einmal ausgeführt werden. Diese Nachricht erscheint so lange, bis das Modul aktiviert und die Aktualisierungen ausgeführt wurden." + +#: content.install:244 +msgid "!module.module has updates and is available in the modules folder but is not enabled.<br />If and when it is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "Für !module.module liegen Aktualisierungen vor. Dieses Modul befindet sich im Modulverzeichnis, ist aber nicht aktiviert.<br />Wenn es aktiviert wird, muss das Aktualisierungsskript noch einmal ausgeführt werden. Diese Nachricht erscheint so lange, bis das Modul aktiviert und die Aktualisierungen ausgeführt wurden." + +#: content.install:251 +msgid "Some updates are still pending. Please return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Einige Aktualisierungen stehen noch aus. Bitte zur <a href=\"@update-php\">update.php</a> zurückkehren und die ausstehenden Aktualisierungen ausführen." + +#: content.install:252 +msgid "Some updates are still pending.<br/>Please re-run the update script." +msgstr "Einige Aktualisierungen stehen noch aus.<br/>Bitte das Aktualisierungsskript noch einmal ausführen." + +#: (duplicate) content.install:10 +msgid "CCK - No Views integration" +msgstr "CCK - Keine Integration von Ansichten" + +#: (duplicate) content.install:11 +msgid "CCK integration with Views module requires Views 6.x-2.0-rc2 or greater." +msgstr "Die CCK-Integration mit dem Views-Modul erfordert Views 6.x-2.0-rc2 oder höher." + +#: content.info:0 +#: includes/content.rules.inc:19;212 +#: includes/views/content.views.inc:180;261 +msgid "Content" +msgstr "Inhalt" + +#: content.info:0 +msgid "Allows administrators to define new content types." +msgstr "Erlaubt dem Administrator, neue Inhaltstypen zu definieren." + +#: content.info:0 +#: modules/content_copy/content_copy.info:0 +#: modules/content_permissions/content_permissions.info:0 +#: modules/fieldgroup/fieldgroup.info:0 +#: modules/nodereference/nodereference.info:0 +#: modules/number/number.info:0 +#: modules/optionwidgets/optionwidgets.info:0 +#: modules/text/text.info:0 +#: modules/userreference/userreference.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/content.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/content.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..11bbdb0b485c384c507ba175675c3ddf595d8e9b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/content.fr.po @@ -0,0 +1,280 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 13:24+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: content.module:25 +msgid "" +"The content module, a required component of the Content Construction Kit " +"(CCK), allows administrators to associate custom fields with content types. " +"In Drupal, content types are used to define the characteristics of a post, " +"including the title and description of the fields displayed on its add and " +"edit pages. Using the content module (and the other helper modules included " +"in CCK), custom fields beyond the default \"Title\" and \"Body\" may be " +"added. CCK features are accessible through tabs on the <a href=\"@content-" +"types\">content types administration page</a>. (See the <a href=\"@node-help" +"\">node module help page</a> for more information about content types.)" +msgstr "" +"Le module Content, composant obligatoire du kit CCK (Content Construction " +"Kit) permet aux administrateurs d'associer des champs personnalisés à des " +"types de contenus. Au sein de Drupal, les types de contenus servent à " +"définir les caractéristiques d'une publication, y compris le titre et la " +"description des champs affichés sur ses pages \"ajouter\" et \"éditer\". Le " +"module Content (et les modules auxiliaires inclus dans CCK) permet d'ajouter " +"des champs personnalisés en plus des champs par défaut \"Titre\" et \"Corps" +"\". Les fonctionnalités de CCK sont accessible via différents onglets sur la " +"<a href=\"@content-types\">page d'administration des types de contenus</a>. " +"(Voir la <a href=\"@node-help\">page d'aide du module Node</a> pour plus " +"d'informations sur les types de contenus)." + +#: content.module:26 +msgid "" +"When adding a custom field to a content type, you determine its type " +"(whether it will contain text, numbers, or references to other objects) and " +"how it will be displayed (either as a text field or area, a select box, " +"checkbox, radio button, or autocompleting field). A field may have multiple " +"values (i.e., a \"person\" may have multiple e-mail addresses) or a single " +"value (i.e., an \"employee\" has a single employee identification number). " +"As you add and edit fields, CCK automatically adjusts the structure of the " +"database as necessary. CCK also provides a number of other features, " +"including intelligent caching for your custom data, an import and export " +"facility for content type definitions, and integration with other " +"contributed modules." +msgstr "" +"Lorsque vous ajoutez un champ personnalisé à un type de contenu, vous " +"déterminez son type (c'est-à-dire s'il doit contenir du texte, des nombres " +"ou des références à d'autres objets) et la façon dont il doit être affiché " +"(en tant que champ ou zone de texte, liste de sélection, case à cocher, " +"bouton radio, ou champ à auto-complètement). Un champ peut présenter " +"plusieurs valeurs (par exemple, une \"personne\" peut disposer de plusieurs " +"adresses courriel) ou une seule (par exemple, un \"employé\" possède un " +"numéro d'identification unique). À mesure que vous ajoutez et modifiez des " +"champs, CCK ajuste automatiquement la structure de la base de données en " +"fonction. CCK propose également un certain nombre d'autres fonctionnalités, " +"par exemple un cache intelligent pour vos données personnalisées, des " +"fonctionnalités d'import et d'export pour les définitions de types de " +"contenus, ainsi qu'une intégration à d'autres modules provenant des " +"contributions." + +#: content.module:27 +msgid "" +"Custom field types are provided by a set of optional modules included with " +"CCK (each module provides a different type). The <a href=\"@modules" +"\">modules page</a> allows you to enable or disable CCK components. A " +"default installation of CCK includes:" +msgstr "" +"Des types de champs personnalisés sont proposés par plusieurs modules " +"optionnels inclus dans CCK (chaque module fournissant un type différent). La " +"<a href=\"@modules\">page des modules</a> vous permet d'activer ou de " +"désactiver des composants CCK. Une installation par défaut de CCK inclut :" + +#: content.module:29 +msgid "" +"<em>number</em>, which adds numeric field types, in integer, decimal or " +"floating point form. You may define a set of allowed inputs, or specify an " +"allowable range of values. A variety of common formats for displaying " +"numeric data are available." +msgstr "" +"<em>Number</em>, qui ajoute des types de champs numériques (formats entier, " +"décimal ou réel à virgule flottante). Vous pouvez définir un jeu ou un " +"intervalle de valeurs autorisées. Divers formats sont disponibles pour " +"l'affichage des données numériques." + +#: content.module:30 +msgid "" +"<em>text</em>, which adds text field types. A text field may contain plain " +"text only, or optionally, may use Drupal's input format filters to securely " +"manage rich text input. Text input fields may be either a single line (text " +"field), multiple lines (text area), or for greater input control, a select " +"box, checkbox, or radio buttons. If desired, CCK can validate the input to a " +"set of allowed values." +msgstr "" +"<em>Text</em>, qui ajoute des types de champs de texte. Un champ texte peut " +"contenir du texte brut uniquement ou, optionnellement, utiliser les filtres " +"des formats d'entrée que propose Drupal pour gérer en toute sécurité des " +"textes enrichis. Les champs de saisie de texte peuvent être constitués d'une " +"seule ligne (champ texte), de plusieurs lignes (zone de texte) ou, pour un " +"meilleur contrôle des valeurs saisies, une liste de sélection, des cases à " +"cocher ou des boutons radio. Si besoin, CCK peut valider les saisies sur la " +"base d'un ensemble de valeurs autorisées." + +#: content.module:31 +msgid "" +"<em>nodereference</em>, which creates custom references between Drupal " +"nodes. By adding a <em>nodereference</em> field and two different content " +"types, for instance, you can easily create complex parent/child " +"relationships between data (multiple \"employee\" nodes may contain a " +"<em>nodereference</em> field linking to an \"employer\" node)." +msgstr "" +"<em>Node Reference</em>, qui crée des références personnalisées entre nœuds " +"de Drupal. En ajoutant, par exemple, un champ <em>nodereference</em> et deux " +"types de contenus différents, vous pouvez facilement créer des relations " +"complexes de type parent/enfant entre données (par exemple plusieurs nœuds " +"\"employé\" peuvent présenter un champ <em>nodereference</em> pointant vers " +"un même nœud \"employeur\")." + +#: content.module:32 +msgid "" +"<em>userreference</em>, which creates custom references to your sites' user " +"accounts. By adding a <em>userreference</em> field, you can create complex " +"relationships between your site's users and posts. To track user involvement " +"in a post beyond Drupal's standard <em>Authored by</em> field, for instance, " +"add a <em>userreference</em> field named \"Edited by\" to a content type to " +"store a link to an editor's user account page." +msgstr "" +"<em>User reference</em>, qui crée des références personnalisées vers les " +"comptes des utilisateurs de votre site. En ajoutant un champ " +"<em>userreference</em>, vous pouvez créer des relations complexes entre les " +"utilisateurs de votre site et des publications. Ainsi, pour tracer " +"l'implication d'un utilisateur dans une publication (au delà du champ Drupal " +"standard <em>Écrit par</em>), vous pouvez ajouter à un type de contenu un " +"champ <em>userreference</em> intitulé \"Édité par\" pour enregistrer un lien " +"vers la page du compte utilisateur ayant édité la publication." + +#: content.module:33 +msgid "" +"<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of " +"related fields. A fieldset may either be open or closed by default. The " +"order of your fieldsets, and the order of fields within a fieldset, is " +"managed via a drag-and-drop interface provided by content module." +msgstr "" +"<em>Fieldgroup</em>, qui crée des groupes de champs liés. Les groupe de " +"champ peuvent être repliés, et vous pouvez choisir qu'ils soient dépliés ou " +"repliés par défaut. L'ordre des groupes de champs, ainsi que l'ordre des " +"champs au sein d'un groupe, est géré grâce à l'interface par glisser-déposer " +"fournie par le module Content." + +#: content.module:35 +msgid "" +"For more information, see the online handbook entry for <a href=\"@handbook-" +"cck\">CCK</a> or the <a href=\"@project-cck\">CCK project page</a>." +msgstr "" +"Pour plus d'informations, reportez-vous à l'entrée de manuel en ligne " +"relative à <a href=\"@handbook-cck\">CCK</a> ou à la <a href=\"@project-cck" +"\">page du projet CCK</a>." + +#: content.module:41 +msgid "" +"Configure how this content type's fields and field labels should be " +"displayed when it's viewed in teaser and full-page mode." +msgstr "" +"Configurez ici la manière dont les champs et étiquettes de champs de ce type " +"de contenu doivent être affichées, lorsque le contenu est vu en mode résumé " +"ou en pleine page." + +#: content.module:44 +msgid "" +"Configure how this content type's fields should be displayed when it's " +"rendered in the following contexts." +msgstr "" +"Configurez ici la façon dont les champs de ce type de contenu doivent être " +"affichés lorsqu'il est rendu dans les contextes suivants." + +#: content.module:48 +msgid "Control the order of fields in the input form." +msgstr "Contrôlez ici l'ordre des champs dans le formulaire de saisie." + +#: content.module:474 +msgid "This field is required." +msgstr "Ce champ est obligatoire." + +#: content.module:478 +msgid "!title: !required" +msgstr "!title : !required" + +#: content.module:481 +msgid "Order" +msgstr "Ordre" + +#: content.module:1640 +msgid "RSS Item" +msgstr "Élément de flux RSS" + +#: content.module:1642 +msgid "Search Index" +msgstr "Index de recherche" + +#: content.module:1643 +msgid "Search Result" +msgstr "Résultat de recherche" + +#: content.module:1981 +msgid "Language" +msgstr "Langue" + +#: content.module:1984 +msgid "Taxonomy" +msgstr "Taxonomie" + +#: content.module:1987 +msgid "File attachments" +msgstr "Fichiers attachés" + +#: content.module:557 +msgid "Updating field type %type with module %module." +msgstr "Mise à jour du type de champ %type avec le module %module." + +#: content.module:564 +msgid "Updating widget type %type with module %module." +msgstr "Mise à jour du type de widget %widget avec le module %module." + +#: content.module:84 +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "" +"Utiliser du code PHP pour le paramétrage des champs (dangereux - à " +"n'autoriser qu'avec précautions)" + +#: content.module:125 +msgid "Manage fields" +msgstr "Gérer les champs" + +#: content.module:134 +msgid "Display fields" +msgstr "Afficher les champs" + +#: content.module:143 +msgid "General" +msgstr "Général" + +#: content.module:149 +msgid "Advanced" +msgstr "Avancé" + +#: content.module:177 +msgid "Remove field" +msgstr "Supprimer un champ" + +#: content.info:0 includes/content.views.inc:54;91 +msgid "Content" +msgstr "Content" + +#: content.info:0 +msgid "Allows administrators to define new content types." +msgstr "Permet aux administrateurs de définir des nouveaux types de contenu." + +#: content.info:0 modules/content_copy/content_copy.info:0 +#: modules/content_permissions/content_permissions.info:0 +#: modules/fieldgroup/fieldgroup.info:0 +#: modules/nodereference/nodereference.info:0 modules/number/number.info:0 +#: modules/optionwidgets/optionwidgets.info:0 modules/text/text.info:0 +#: modules/userreference/userreference.info:0 +msgid "CCK" +msgstr "CCK" + +#: examples/example_field.php:107 examples/simple_field.php:115 +#: modules/text/text.module:49 modules/text/text.info:0 +msgid "Text" +msgstr "Texte" diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/content.pot b/drupal/sites/default/boinc/modules/contrib/cck/translations/content.pot new file mode 100644 index 0000000000000000000000000000000000000000..86bafd2529d9d0c33fd273353ec05e60f45574f9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/content.pot @@ -0,0 +1,236 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (root) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content.module,v 1.301.2.106 2009/06/02 12:24:04 yched +# content.install,v 1.85.2.31 2009/04/23 18:37:10 yched +# content.info,v 1.6 2007/07/04 23:46:29 yched +# content.rules.inc,v 1.1.2.6 2009/04/30 09:56:07 fago +# content.views.inc,v 1.1.2.25 2009/04/11 14:50:53 yched +# content_copy.info,v 1.6 2008/04/23 18:01:48 dww +# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww +# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens +# nodereference.info,v 1.8 2008/04/23 18:02:07 dww +# number.info,v 1.7 2008/04/23 18:02:16 dww +# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww +# text.info,v 1.9 2008/04/23 18:02:31 dww +# userreference.info,v 1.8 2008/04/23 18:02:38 dww +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: content.module:21 +msgid "The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default \"Title\" and \"Body\" may be added. CCK features are accessible through tabs on the <a href=\"@content-types\">content types administration page</a>. (See the <a href=\"@node-help\">node module help page</a> for more information about content types.)" +msgstr "" + +#: content.module:22 +msgid "When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a \"person\" may have multiple e-mail addresses) or a single value (i.e., an \"employee\" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules." +msgstr "" + +#: content.module:23 +msgid "Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href=\"@modules\">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:" +msgstr "" + +#: content.module:25 +msgid "<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available." +msgstr "" + +#: content.module:26 +msgid "<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values." +msgstr "" + +#: content.module:27 +msgid "<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple \"employee\" nodes may contain a <em>nodereference</em> field linking to an \"employer\" node)." +msgstr "" + +#: content.module:28 +msgid "<em>userreference</em>, which creates custom references to your sites' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site's users and posts. To track user involvement in a post beyond Drupal's standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named \"Edited by\" to a content type to store a link to an editor's user account page." +msgstr "" + +#: content.module:29 +msgid "<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module." +msgstr "" + +#: content.module:31 +msgid "For more information, see the online handbook entry for <a href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK project page</a>." +msgstr "" + +#: content.module:492 +msgid "This field is required." +msgstr "" + +#: content.module:496 +msgid "!title: !required" +msgstr "" + +#: content.module:1854 +msgid "Basic" +msgstr "" + +#: content.module:1867;1870 +msgid "RSS" +msgstr "" + +#: content.module:1880 +msgid "Search" +msgstr "" + +#: content.module:1883 +msgid "Search Index" +msgstr "" + +#: content.module:1887 +msgid "Search Result" +msgstr "" + +#: content.module:1897;1900 +msgid "Print" +msgstr "" + +#: content.module:2348;2355 +msgid "Node module form." +msgstr "" + +#: content.module:2362 +msgid "Language" +msgstr "" + +#: content.module:2363 +msgid "Locale module form." +msgstr "" + +#: content.module:2369 +msgid "Menu settings" +msgstr "" + +#: content.module:2370 +msgid "Menu module form." +msgstr "" + +#: content.module:2376 +msgid "Taxonomy" +msgstr "" + +#: content.module:2377 +msgid "Taxonomy module form." +msgstr "" + +#: content.module:2383 +msgid "Book" +msgstr "" + +#: content.module:2384 +msgid "Book module form." +msgstr "" + +#: content.module:2390 +msgid "Poll title" +msgstr "" + +#: content.module:2391 +msgid "Poll module title." +msgstr "" + +#: content.module:2395 +msgid "Poll choices" +msgstr "" + +#: content.module:2396 +msgid "Poll module choices." +msgstr "" + +#: content.module:2400 +msgid "Poll settings" +msgstr "" + +#: content.module:2401 +msgid "Poll module settings." +msgstr "" + +#: content.module:2407 +msgid "File attachments" +msgstr "" + +#: content.module:2408 +msgid "Upload module form." +msgstr "" + +#: content.module:595 +msgid "Updating field type %type with module %module." +msgstr "" + +#: content.module:602 +msgid "Updating widget type %type with module %module." +msgstr "" + +#: content.module:60 +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "" + +#: content.module:79 +msgid "Fields" +msgstr "" + +#: content.module:101 +msgid "Manage fields" +msgstr "" + +#: content.module:110 +msgid "Display fields" +msgstr "" + +#: content.module:141 +msgid "Remove field" +msgstr "" + +#: content.install:236 +msgid "Updates for CCK-related modules are not run until the modules are enabled on the <a href=\"@admin-modules-path\">administer modules page</a>. When you enable them, you'll need to return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "" + +#: content.install:239 +msgid "!module.module has updates but cannot be updated because content.module is not enabled.<br />If and when content.module is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "" + +#: content.install:244 +msgid "!module.module has updates and is available in the modules folder but is not enabled.<br />If and when it is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "" + +#: content.install:251 +msgid "Some updates are still pending. Please return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "" + +#: content.install:252 +msgid "Some updates are still pending.<br/>Please re-run the update script." +msgstr "" + +#: (duplicate) content.install:10 +msgid "CCK - No Views integration" +msgstr "" + +#: (duplicate) content.install:11 +msgid "CCK integration with Views module requires Views 6.x-2.0-rc2 or greater." +msgstr "" + +#: content.info:0 includes/content.rules.inc:19;212 includes/views/content.views.inc:180;261 +msgid "Content" +msgstr "" + +#: content.info:0 +msgid "Allows administrators to define new content types." +msgstr "" + +#: content.info:0 modules/content_copy/content_copy.info:0 modules/content_permissions/content_permissions.info:0 modules/fieldgroup/fieldgroup.info:0 modules/nodereference/nodereference.info:0 modules/number/number.info:0 modules/optionwidgets/optionwidgets.info:0 modules/text/text.info:0 modules/userreference/userreference.info:0 +msgid "CCK" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/content.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/content.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..65e71c2ab0e30d767250d4481f0de308ce608643 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/content.sv.po @@ -0,0 +1,243 @@ +# $Id$ +# +# Swedish translation of Drupal (content) +# Generated from files: +# content.module,v 1.301.2.99 2009/03/05 22:58:57 karens +# content.install,v 1.85.2.30 2008/11/07 16:24:58 yched +# content.info,v 1.6 2007/07/04 23:46:29 yched +# content.rules.inc,v 1.1.2.4 2008/10/24 11:11:48 fago +# content.views.inc,v 1.1.2.22 2009/01/14 13:19:47 karens +# content_copy.info,v 1.6 2008/04/23 18:01:48 dww +# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww +# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens +# nodereference.info,v 1.8 2008/04/23 18:02:07 dww +# number.info,v 1.7 2008/04/23 18:02:16 dww +# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww +# text.info,v 1.9 2008/04/23 18:02:31 dww +# userreference.info,v 1.8 2008/04/23 18:02:38 dww +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Content 6.x\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-05-27 15:37+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: content.module:21 +msgid "The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default \"Title\" and \"Body\" may be added. CCK features are accessible through tabs on the <a href=\"@content-types\">content types administration page</a>. (See the <a href=\"@node-help\">node module help page</a> for more information about content types.)" +msgstr "Modulen Content, en obligatorisk komponent till Content Construction Kit (CCK), gör det möjligt för administratörer att associera anpassade fält med innehållstyper. I Drupal används innehållstyper för att definiera ett inläggs karaktäristik, såsom titel och beskrivning för fälten som visas på dess sidor för att lägga till redigera. Genom att använda modulen Content (och de andra hjälpmodulerna inkluderade i CCK), kan egna fält utöver standardfälten \"Titel\" och \"Brödtext\" läggas till. Funktionerna för CCK är tillgängliga genom flikarna på sidan<a href=\"@content-types\">admininistrera innehållstyper</a>. (Se sidan <a href=\"@node-help\">hjälp för modulen Nod</a> för mer information om innehållstyper.)" + +#: content.module:22 +msgid "When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a \"person\" may have multiple e-mail addresses) or a single value (i.e., an \"employee\" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules." +msgstr "När du lägger till ett anpassat fält till en innehållstyp, bestämmer du dess typ (om det ska innehålla text, nummer eller referera till andra objekt) och hur det ska visas (antingen som ett textfält, flerradigt textfält, listval, kryssruta, radioknapp eller autokomatiskt kompletterande fält). Ett fält kan ha flera värden (till exempel kan en \"person\" ha flera e-postadresser) eller ett värda (till exempel kan en \"anställd\" ha ett anställnings-ID). När du lägger till och redigerar fält kommer CCK automatiskt att justera databasens struktur. CCK möjliggör även ett antal andra funktioner, såsom intelligent caching för dina anpassade data, import och export av definitioner av innehållstyper samt integration med andra tilläggsmoduler." + +#: content.module:23 +msgid "Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href=\"@modules\">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:" +msgstr "Anpassade fälttyper är tillgängliga genom ett antal valfria moduler som är inkluderade med CCK (varje modul tillhandahåller en egen typ). Sidan <a href=\"@modules\">moduler</a> låter dig aktivera eller eller inaktivera komponenter för CCK. En standardinstallation av CCK inkluderar:" + +#: content.module:25 +msgid "<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available." +msgstr "<em>tal</em>, som lägger till numeriska fälttyper som heltal, decimaltal eller flyttal. Du kan definiera en uppsättning av tillåtna värden eller specificera en tillåten spännvidd av värden. Ett antal vanliga format för att visa numerisk data finns tillgängliga." + +#: content.module:26 +msgid "<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values." +msgstr "<em>text</em>, som lägger till typer av sorten textfält. Ett textfält kan innehålla enbart ren text, eller använda Drupals inmatningsformat för att säkert hantera formaterad text. Textfält kan vara antingen en rad (textfält), flera rader (textområde), eller för större kontroll av det som matas in, ett listval, kryssruta eller radioknapp. Om så önskas kan CCK validera den inmatade datan enligt en uppsättning tillåtna värden." + +#: content.module:27 +msgid "<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple \"employee\" nodes may contain a <em>nodereference</em> field linking to an \"employer\" node)." +msgstr "<em>hänvisning av nod</em>, som skapar hänvisningar mellan noder i Drupal. Genom att lägga till en fält av typen <em>nodreferens</em> och två olika innehållstyper, till exempel, kan du enkelt skapa komplexa ovan- eller underliggande relationer mellan data (flera noder med \"anställda\" kan innehålla ett fält av typen <em>nodreferens</em> som länkar till en nod för \"arbetsgivare\")." + +#: content.module:28 +msgid "<em>userreference</em>, which creates custom references to your sites' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site's users and posts. To track user involvement in a post beyond Drupal's standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named \"Edited by\" to a content type to store a link to an editor's user account page." +msgstr "<em>hänvisning av användare</em>, som skapar anpassade hänvisningar till användarkonton på din webbplats. Genom att lägga till ett fält av typen <em>användarreferens</em> kan du skapa komplexa relationer mellan din webbplats användare och inlägg. Till exempel: för att spåra användares inblandning i ett inlägg utöver Drupals standardfält <em>Författad av</em>, lägg till ett fält av typen <em>användarreferens</em> med namnet \"Redigerad av\" till en innehållstyp för att lagra en länk till en redigerares användarsida." + +#: content.module:29 +msgid "<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module." +msgstr "<em>fältgrupp</em>, som skapar hopfällbara fältgrupp för att innehålla en grupp av relaterade fält. En fältgrupp kan antingen vara öppen eller hopfälld som standard. Sorteringen av fältgrupper, och sorteringen av fält inom en fältgrupp, hanteras genom ett drag-och-släpp-gränssnitt via modulen Content." + +#: content.module:31 +msgid "For more information, see the online handbook entry for <a href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK project page</a>." +msgstr "För mer information, <a href=\"@handbook-cck\">läs onlinehandboken för CCK</a> eller besök <a href=\"@project-cck\">CCK:s projektsida</a>." + +#: content.module:486 +msgid "This field is required." +msgstr "Detta fält är obligatoriskt." + +#: content.module:490 +msgid "!title: !required" +msgstr "!title: !required" + +#: content.module:1843 +msgid "Basic" +msgstr "Grundläggande" + +#: content.module:1856;1859 +msgid "RSS" +msgstr "RSS" + +#: content.module:1869 +msgid "Search" +msgstr "Sök" + +#: content.module:1872 +msgid "Search Index" +msgstr "Sökindex" + +#: content.module:1876 +msgid "Search Result" +msgstr "Sökresultat" + +#: content.module:2324;2331 +msgid "Node module form." +msgstr "Formulär för modulen Nod." + +#: content.module:2338 +msgid "Language" +msgstr "Språk" + +#: content.module:2339 +msgid "Locale module form." +msgstr "Formulär för modulen Språkanpassning.." + +#: content.module:2345 +msgid "Menu settings" +msgstr "Menyinställningar" + +#: content.module:2346 +msgid "Menu module form." +msgstr "Formulär för modulen Meny." + +#: content.module:2352 +msgid "Taxonomy" +msgstr "Taxonomi" + +#: content.module:2353 +msgid "Taxonomy module form." +msgstr "Formulär för modulen Taxonomi." + +#: content.module:2359 +msgid "Book" +msgstr "Bok" + +#: content.module:2360 +msgid "Book module form." +msgstr "Formulär för modulen Bok." + +#: content.module:2366 +msgid "Poll title" +msgstr "Titel för omröstning" + +#: content.module:2367 +msgid "Poll module title." +msgstr "Titel för modulen Omröstning." + +#: content.module:2371 +msgid "Poll choices" +msgstr "Val för omröstning" + +#: content.module:2372 +msgid "Poll module choices." +msgstr "Val för modulen Omröstning." + +#: content.module:2376 +msgid "Poll settings" +msgstr "Inställningar för omröstning" + +#: content.module:2377 +msgid "Poll module settings." +msgstr "Inställningar för modulen Omröstning." + +#: content.module:2383 +msgid "File attachments" +msgstr "Bifogade filer" + +#: content.module:2384 +msgid "Upload module form." +msgstr "Formulär för modulen Uppladdning." + +#: content.module:589 +msgid "Updating field type %type with module %module." +msgstr "Uppdaterar fälttypen %type med modulen %module." + +#: content.module:596 +msgid "Updating widget type %type with module %module." +msgstr "Uppdaterar gränssnittskomponenten %type med modulen %module." + +#: content.module:63 +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "Använd PHP-inmatning för fältinställningarna (farligt - använd med försiktighet)" + +#: content.module:82 +msgid "Fields" +msgstr "Fält" + +#: content.module:104 +msgid "Manage fields" +msgstr "Hantera fält" + +#: content.module:113 +msgid "Display fields" +msgstr "Visa fält" + +#: content.module:144 +msgid "Remove field" +msgstr "Ta bort fält" + +#: content.install:236 +msgid "Updates for CCK-related modules are not run until the modules are enabled on the <a href=\"@admin-modules-path\">administer modules page</a>. When you enable them, you'll need to return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Uppdateringar för relaterade moduler till CCK körs inte förrän modulerna är aktiverade på sidan <a href=\"@admin-modules-path\">administrera moduler</a>. När du aktiverar dem kommer du att behöva återvända till <a href=\"@update-php\">update.php</a> och köra de kvarvarande uppdateringarna." + +#: content.install:239 +msgid "!module.module has updates but cannot be updated because content.module is not enabled.<br />If and when content.module is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "!module.module har uppdateringar men kan inte uppdateras eftersom content.module inte är aktiverad.<br />Om och när content.module är aktiverad kommer du att behöva köra uppdateringsskriptet igen. Du kommer att fortsätta se detta meddelande tills modulen är aktiverad och uppdateringarna är genomförda." + +#: content.install:244 +msgid "!module.module has updates and is available in the modules folder but is not enabled.<br />If and when it is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "!module.module har uppdateringar och är tillgänglig i katalogen för moduler men är inte aktiverad.<br /> Om och när den är aktiverad kommer du att behöva köra uppdateringsskriptet igen. Du kommer att fortsätta se detta meddelande tills modulen är aktiverad och uppdateringarna är genomförda." + +#: content.install:251 +msgid "Some updates are still pending. Please return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Några uppdateringar är fortfarande kvar. Vänligen återvänd till <a href=\"@update-php\">update.php</a> och kör de kvarvarande uppdateringarna." + +#: content.install:252 +msgid "Some updates are still pending.<br/>Please re-run the update script." +msgstr "Några uppdateringar är fortfarande kvar.<br/>Var vänlig kör uppdateringsskriptet igen." + +#: (duplicate) content.install:10 +msgid "CCK - No Views integration" +msgstr "CCK - Ingen integration med Views" + +#: (duplicate) content.install:11 +msgid "CCK integration with Views module requires Views 6.x-2.0-rc2 or greater." +msgstr "Integration av CCK med modulen Views kräver Views 6.x-2.0-rc2 eller senare." + +#: content.info:0 +#: includes/content.rules.inc:19;200 +#: includes/views/content.views.inc:178;254 +msgid "Content" +msgstr "Innehåll" + +#: content.info:0 +msgid "Allows administrators to define new content types." +msgstr "Tillåter administratörer att definiera nya innehållstyper." + +#: content.info:0 +#: modules/content_copy/content_copy.info:0 +#: modules/content_permissions/content_permissions.info:0 +#: modules/fieldgroup/fieldgroup.info:0 +#: modules/nodereference/nodereference.info:0 +#: modules/number/number.info:0 +#: modules/optionwidgets/optionwidgets.info:0 +#: modules/text/text.info:0 +#: modules/userreference/userreference.info:0 +msgid "CCK" +msgstr "CCK" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/es.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/es.po new file mode 100644 index 0000000000000000000000000000000000000000..4681c612ddc27812d08101ca09ec97f1f9b283dc --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/es.po @@ -0,0 +1,403 @@ +# $Id$ +# LANGUAGE translation of Drupal (general) +# Copyright 2006 NAME <EMAIL@ADDRESS> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 JonBob +# text.module,v 1.34 2006/06/12 19:59:53 JonBob +# number.module,v 1.28 2006/05/02 13:52:16 JonBob +# content_admin.inc,v 1.16 2006/06/12 19:36:54 JonBob +# content.module,v 1.64 2006/06/12 19:36:54 JonBob +# nodereference.module,v 1.28 2006/06/12 19:36:54 JonBob +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 JonBob +# userreference.module,v 1.24 2006/05/05 14:10:44 JonBob +# weburl.module,v 1.8 2006/06/12 19:36:54 JonBob +# +msgid "" +msgstr "" +"Project-Id-Version: cck.module 4.7\n" +"POT-Creation-Date: 2006-07-05 13:23-0400\n" +"PO-Revision-Date: 2006-07-17 08:30-0300\n" +"Last-Translator: Guillermo Acedo <guillermo.acedo@gmail.com>\n" +"Language-Team: Spanish <es@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\\n\n" + +#: field.php:77 +#: text.module:44 +msgid "Maximum length" +msgstr "Longitud máxima" + +#: field.php:80 +#: text.module:47 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "La longitud máxima del campo en caracteres. Déjalo en blanco para un tamaño ilimitado." + +#: field.php:102 +#: number.module:82 +#: text.module:80 +msgid "is equal to" +msgstr "es igual a" + +#: field.php:103 +#: number.module:83 +#: text.module:81 +msgid "is not equal to" +msgstr "no es igual a" + +#: field.php:104 +#: text.module:82 +msgid "matches the pattern" +msgstr "coincide con el patrón" + +#: field.php:180;190 +#: number.module:119 +#: text.module:107 +msgid "Illegal value for %name." +msgstr "Valor ilegal para %name." + +#: field.php:265 +#: text.module:159 +msgid "Rows" +msgstr "Filas" + +#: field.php:273 +#: text.module:167 +msgid "\"Rows\" must be a positive integer." +msgstr "\"Filas\" debe ser un valor positivo entero." + +#: content_admin.inc:25 +#: content.module:119 +msgid "duplicate" +msgstr "duplicar" + +#: number.module:48 +#: text.module:51 +msgid "Allowed values" +msgstr "Valores permitidos" + +#: number.module:52 +#: text.module:55 +msgid "The possible values this field can contain. Any other values will result in an error. Enter one value per line." +msgstr "Los valores posibles que este campo puede contener. Cualquier otro valor puede dará error. Ingresar un valor por linea." + +#: content.module:18 +msgid "Allows administrators to define new content types." +msgstr "Permitir a los administradores definir nuevos tipos de contenidos." + +#: content.module:73 +msgid "add content type" +msgstr "añadir un tipo de contenido" + +#: content.module:80 +msgid "fields" +msgstr "los campos" + +#: content.module:135 +msgid "manage fields" +msgstr "configurar los campos" + +#: content.module:164 +msgid "remove field" +msgstr "borrar el campo" + +#: nodereference.module:15 +msgid "Defines a field type for referencing one node from another. <em>Note: Requires content.module.</em>" +msgstr "Define un tipo de campo para referenciar un nodo de otro. <em>Nota: Requiere content.module.</em>" + +#: nodereference.module:26 +msgid "node reference autocomplete" +msgstr "autocompletar nodo de referencia" + +#: nodereference.module:51 +msgid "Content types that can be referenced" +msgstr "Tipos de contenido que pueden ser referenciados" + +#: nodereference.module:204 +msgid "No post with that title exists." +msgstr "No existe ninguna publicación con ese título." + +#: nodereference.module:0 +msgid "nodereference" +msgstr "nodo de referencia" + +#: number.module:15 +msgid "Defines numeric field types. <em>Note: Requires content.module.</em>" +msgstr "Define los tipos de campo numéricos. <em>Nota: Requiere content.module.</em>" + +#: number.module:38 +msgid "Minimum" +msgstr "Mínimo" + +#: number.module:43 +msgid "Maximum" +msgstr "Máximo" + +#: number.module:58 +msgid "\"Minimum\" must be a number." +msgstr "\"Mínimo\" debe ser un número." + +#: number.module:61 +msgid "\"Maximum\" must be a number." +msgstr "\"Máximo\"debe ser un número." + +#: number.module:113 +msgid "The value of %name may be no smaller than %min." +msgstr "El valor de %name no debe ser menor que %min." + +#: number.module:116 +msgid "The value of %name may be no larger than %max." +msgstr "El valor de %name no debe ser mayor que %max." + +#: number.module:0 +msgid "number" +msgstr "número" + +#: optionwidgets.module:15 +msgid "Defines selection, check box and radio button widgets for text and numeric fields. <em>Note: Requires content.module, text.module and number.module.</em>" +msgstr "Define controles de selección, check box y radio button para campos de texto y numéricos. <em>Nota: Requiere content.module, text.module y number.module.</em>" + +#: optionwidgets.module:0 +msgid "optionwidgets" +msgstr "optionwidgets" + +#: text.module:15 +msgid "Defines simple text field types. <em>Note: Requires content.module.</em>" +msgstr "Define tipos de campo de texto simple. <em>Nota: Requiere content.module.</em>" + +#: text.module:35 +msgid "Plain text" +msgstr "Sólo texto" + +#: text.module:35 +msgid "Filtered text (user selects input format)" +msgstr "Texto filtrado (los usuarios seleccionan el formato de entrada)" + +#: text.module:38 +msgid "Text processing" +msgstr "Procesando texto" + +#: text.module:0 +msgid "text" +msgstr "texto" + +#: userreference.module:15 +msgid "Defines a field type for referencing a user from a node. <em>Note: Requires content.module.</em>" +msgstr "Define un tipo de campo para referenciar un usuario desde un nodo. <em>Nota: Requiere content.module.</em>" + +#: userreference.module:176 +msgid "Invalid user name." +msgstr "Nombre de usuario no válido" + +#: userreference.module:0 +msgid "userreference" +msgstr "userreference" + +#: weburl.module:15 +msgid "Defines simple weburl field types. <em>Note: Requires content.module.</em>" +msgstr "Define tipo de campo para dirección de Web. <em>Nota: Requiere content.module.</em>" + +#: weburl.module:164;172 +msgid "Not a valid Web URL." +msgstr "No es una dirección de pagina Web válida" + +#: weburl.module:0 +msgid "weburl" +msgstr "weburl" + +#: content_admin.inc:16;87;232;310;533 +msgid "Label" +msgstr "Etiqueta" + +#: content_admin.inc:42 +msgid "Content types" +msgstr "Tipo de contenido" + +#: content_admin.inc:90 +msgid "The human-readable name of this content type." +msgstr "El nombre legible de este tipo de contenido." + +#: content_admin.inc:98 +msgid "A brief description of the content type." +msgstr "Una breve descripción del tipo de contenido." + +#: content_admin.inc:106 +msgid "Instructions to present to the user when adding new content of this type." +msgstr "Instrucciones a presentar al usuario cuando agrega este tipo de contenido." + +#: content_admin.inc:110 +msgid "Title field label" +msgstr "Etiqueta del campo Título" + +#: content_admin.inc:113 +msgid "The label for the title field." +msgstr "La etiqueta para el campo del título." + +#: content_admin.inc:118 +msgid "Save content type" +msgstr "Guardar este tipo de contenido" + +#: content_admin.inc:182 +msgid "Saved content type %type." +msgstr "Tipo de contenido %type guardado." + +#: content_admin.inc:198 +msgid "Are you sure you want to delete the content type %type?" +msgstr "¿Está seguro que quiere borrar el tipo de contenido %type?" + +#: content_admin.inc:198 +msgid "If you have any content left in this content type, it will be permanently deleted. This action cannot be undone." +msgstr "Si existe contenido de este tipo en la base de datos, será borrado de forma permanente. Esta acción no se puede deshacer." + +#: content_admin.inc:218 +msgid "Deleted content type %type." +msgstr "Tipo de contenido %type borrado." + +#: content_admin.inc:248 +msgid "remove" +msgstr "borrar" + +#: content_admin.inc:277 +msgid "Add existing field" +msgstr "Añadir un campo existente" + +#: content_admin.inc:286 +msgid "Add field" +msgstr "Añadir un campo" + +#: content_admin.inc:307 +msgid "Create new field" +msgstr "Crear un nuevo campo" + +#: content_admin.inc:313 +msgid "The human-readable name of this field." +msgstr "El nombre leíble-por-humanos de este campo." + +#: content_admin.inc:318 +msgid "Field type" +msgstr "Tipo de campo" + +#: content_admin.inc:326 +msgid "Create field" +msgstr "Crear un campo" + +#: content_admin.inc:335 +msgid "No field modules are enabled. You need to <a href=\"%modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "No hay ningún módulo de definición de campos habilitados. Usted debe <a href=\"%modules_url\">habilitar uno</a>, por ejemplo como text.module, antes que pueda añadir nuevos campos." + +#: content_admin.inc:389 +msgid "Added field %label." +msgstr "Campo %label agregado." + +#: content_admin.inc:432 +msgid "Created field %label." +msgstr "campo %label creado." + +#: content_admin.inc:452 +msgid "Are you sure you want to remove the field %field?" +msgstr "¿Está seguro que quiere borrar el campo %field?" + +#: content_admin.inc:452 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Si tiene algún contenido en este campo, va a ser permanentemente borrado. Esta acción no podrá deshacerse." + +#: content_admin.inc:452 +msgid "Remove" +msgstr "Borrar" + +#: content_admin.inc:468 +msgid "Removed field %field from %type." +msgstr "Campo %field de %type borrado." + +#: content_admin.inc:487 +msgid "The field %field no longer exists in any content type, so it was deleted." +msgstr "El campo %field no existe mas en ningún tupo de contenido, ha sido borrado." + +#: content_admin.inc:511 +msgid "Widget settings" +msgstr "Opciones del control" + +#: content_admin.inc:512 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Estas configuraciónes se aplican solamente al campo %field como aparece en el tipo de contenido %type. " + +#: content_admin.inc:526 +msgid "Widget" +msgstr "Control" + +#: content_admin.inc:541 +msgid "In the node editing form, the heavier fields will sink and the lighter fields will be positioned nearer the top." +msgstr "En el formulario de edición de nodo, los campos más pesado se posicionarán más hacia abajo y los campos más livianos hacia más arriba." + +#: content_admin.inc:552 +msgid "Instructions to present to the user below this field on the editing form." +msgstr "Las instrucciones a presentan al usuario debajo este campo en el formulario de edición." + +#: content_admin.inc:558 +msgid "Data settings" +msgstr "Configuraciónes de datos" + +#: content_admin.inc:559 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Estas configuraciones se aplica al campo %field en cada tipo de contenido que este aparezca." + +#: content_admin.inc:568 +msgid "Multiple values" +msgstr "Valores múltiples" + +#: content_admin.inc:579 +msgid "Save field settings" +msgstr "Guardar configuraciones del campo" + +#: content_admin.inc:652 +msgid "Saved field %field." +msgstr "campo %field guardado." + +#: content_admin.inc:882;971 +msgid "No PostgreSQL mapping found for %type data type." +msgstr "El mapeo PostgreSQL no se ha encontrado para el tipo de datos %type." + +#: content_admin.inc:882;971 +msgid "database" +msgstr "base de datos" + +#: date.module:15 +msgid "Defines a date/time field type. <em>Note: Requires content.module.</em>" +msgstr "Definir un tipo de campo de fecha/hora. <em>Note: Requiere content.module.</em>" + +#: date.module:36 +msgid "Year" +msgstr "Año" + +#: date.module:37 +msgid "Year and month" +msgstr "Año y mes" + +#: date.module:39 +msgid "Date and time" +msgstr "Día y hora" + +#: date.module:40 +msgid "Time only" +msgstr "Sólo hora" + +#: date.module:44 +msgid "Granularity" +msgstr "Granularity" + +#: date.module:102 +msgid "Times are entered and displayed with site's time zone" +msgstr "El horario debe ser ingresado y visualizado a partir de la zona horaria del sitio" + +#: date.module:103 +msgid "Times are entered and displayed with user's time zone" +msgstr "El horario debe ser ingresado y visualizado a partir de la zona horaria del usuario" + +#: date.module:107 +msgid "Time zone handling" +msgstr "Configurar zona horaria" + +#: date.module:153 +msgid "%name must be entered in ISO 8601 format (YYYYMMDDThh:mm:ss)." +msgstr "%name debe ser ingresado en formato ISO 8601 t (AAAMMDDThh:mm:ss)." \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/examples.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/examples.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..55c5f31697a7bde15f811174da4a65e43de78d14 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/examples.fr.po @@ -0,0 +1,34 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 13:24+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: examples/example_field.php:178 +msgid "" +"The possible values this field can contain. Enter one value per line, in the " +"format key|label. The key is the value that will be stored in the database " +"and it must match the field storage type, %type. The label is optional and " +"the key will be used as the label if no label is specified." +msgstr "" +"Les valeurs possibles pour ce champ. Saisissez une valeur par ligne, sous la " +"forme <em>clé|libellé</em>. La clé est la valeur enregistrée dans la base de " +"données, et elle doit correspondre au type de stockage du champ, %type. Le " +"libellé est optionnel et, s'il n'est pas spécifié, la clé sera utilisée " +"comme libellé." + +#: examples/example_field.php:484 +msgid "Text area" +msgstr "Zone de texte" diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/fr.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/fr.po new file mode 100644 index 0000000000000000000000000000000000000000..ef8b240f0e5b6188488b8f3ebc9601bd9ba53a2b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/fr.po @@ -0,0 +1,2020 @@ +# $Id$ +# +# French translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content.module,v 1.301.2.100 2009/03/18 19:20:52 yched +# content_multigroup.module,v 1.1.2.4 2008/10/22 11:02:41 yched +# content.admin.inc,v 1.181.2.64 2009/03/01 13:48:44 yched +# fieldgroup.module,v 1.79.2.45 2009/02/28 23:56:17 yched +# nodereference.module,v 1.138.2.50 2009/03/18 21:00:58 yched +# content.crud.inc,v 1.76.2.14 2008/11/07 15:02:02 yched +# content.install,v 1.85.2.30 2008/11/07 16:24:58 yched +# content.info,v 1.6 2007/07/04 23:46:29 yched +# content.rules.inc,v 1.1.2.4 2008/10/24 11:11:48 fago +# content.views.inc,v 1.1.2.22 2009/01/14 13:19:47 karens +# content_copy.info,v 1.6 2008/04/23 18:01:48 dww +# modules/content_multigroup/content_multigroup.info: n/a +# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww +# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens +# nodereference.info,v 1.8 2008/04/23 18:02:07 dww +# number.info,v 1.7 2008/04/23 18:02:16 dww +# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww +# text.info,v 1.9 2008/04/23 18:02:31 dww +# userreference.info,v 1.8 2008/04/23 18:02:38 dww +# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched +# content-admin-field-overview-form.tpl.php,v 1.1.2.5 2008/10/16 14:40:54 yched +# content.panels.inc,v 1.1.2.6 2008/11/03 14:12:41 yched +# content_handler_field.inc,v 1.1.2.14 2009/03/18 19:20:52 yched +# content-admin-display-overview-form.tpl.php,v 1.1.2.3 2008/10/09 20:58:26 karens +# number.module,v 1.91.2.33 2009/03/16 22:04:07 yched +# text.module,v 1.95.2.28 2008/12/30 00:00:54 yched +# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched +# content.node_form.inc,v 1.7.2.18 2009/02/10 22:53:04 yched +# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched +# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# content.token.inc,v 1.5.2.8 2008/12/05 14:59:22 yched +# content_handler_field_multiple.inc,v 1.1.2.16 2009/03/17 22:58:06 yched +# content_handler_relationship.inc,v 1.1.2.3 2008/10/24 12:31:58 yched +# content_handler_sort.inc,v 1.1.2.6 2008/10/25 00:36:41 yched +# content_permissions.module,v 1.5.2.5 2008/12/27 22:22:55 yched +# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens +# userreference.module,v 1.106.2.36 2009/03/18 21:00:58 yched +# optionwidgets.module,v 1.69.2.23 2009/03/18 21:00:58 yched +# theme.inc,v 1.1.2.12 2008/10/28 22:12:09 yched +# theme/content-edit.js: n/a +# +msgid "" +msgstr "" +"Project-Id-Version: French Translation for drupal cck module\n" +"POT-Creation-Date: 2009-03-26 16:52+0100\n" +"PO-Revision-Date: 2009-03-26 18:09+0100\n" +"Last-Translator: Sylvain Moreau <sylvain.moreau@ows.fr>\n" +"Language-Team: Sylvain Moreau, OWS <sylvain.moreau@ows.fr>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n>1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" + +#: content.module:21 +msgid "The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default \"Title\" and \"Body\" may be added. CCK features are accessible through tabs on the <a href=\"@content-types\">content types administration page</a>. (See the <a href=\"@node-help\">node module help page</a> for more information about content types.)" +msgstr "Le module Content, composant obligatoire du kit CCK (Content Construction Kit) permet aux administrateurs d'associer des champs personnalisés à des types de contenus. Au sein de Drupal, les types de contenus servent à définir les caractéristiques d'une publication, y compris le titre et la description des champs affichés sur ses pages \"ajouter\" et \"éditer\". Le module Content (et les modules auxiliaires inclus dans CCK) permet d'ajouter des champs personnalisés en plus des champs par défaut \"Titre\" et \"Corps\". Les fonctionnalités de CCK sont accessible via différents onglets sur la <a href=\"@content-types\">page d'administration des types de contenus</a>. (Voir la <a href=\"@node-help\">page d'aide du module Node</a> pour plus d'informations sur les types de contenus)." + +#: content.module:22 +msgid "When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a \"person\" may have multiple e-mail addresses) or a single value (i.e., an \"employee\" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules." +msgstr "Lorsque vous ajoutez un champ personnalisé à un type de contenu, vous déterminez son type (c'est-à-dire s'il doit contenir du texte, des nombres ou des références à d'autres objets) et la façon dont il doit être affiché (en tant que champ ou zone de texte, liste de sélection, case à cocher, bouton radio, ou champ à auto-complètement). Un champ peut présenter plusieurs valeurs (par exemple, une \"personne\" peut disposer de plusieurs adresses e-mail) ou une seule (par exemple, un \"employé\" possède un numéro d'identification unique). À mesure que vous ajoutez et modifiez des champs, CCK ajuste automatiquement la structure de la base de données en fonction. CCK propose également un certain nombre d'autres fonctionnalités, par exemple un cache intelligent pour vos données personnalisées, des fonctionnalités d'import et d'export pour les définitions de types de contenus, ainsi qu'une intégration à d'autres modules provenant des contributions." + +#: content.module:23 +msgid "Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href=\"@modules\">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:" +msgstr "Des types de champs personnalisés sont proposés par plusieurs modules optionnels inclus dans CCK (chaque module fournissant un type différent). La <a href=\"@modules\">page des modules</a> vous permet d'activer ou de désactiver des composants CCK. Une installation par défaut de CCK inclut :" + +#: content.module:25 +msgid "<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available." +msgstr "<em>Number</em>, qui ajoute des types de champs numériques (formats entier, décimal ou réel à virgule flottante). Vous pouvez définir un jeu ou un intervalle de valeurs autorisées. Divers formats sont disponibles pour l'affichage des données numériques." + +#: content.module:26 +msgid "<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values." +msgstr "<em>Text</em>, qui ajoute des types de champs de texte. Un champ texte peut contenir du texte brut uniquement ou, optionnellement, utiliser les filtres des formats d'entrée que propose Drupal pour gérer en toute sécurité des textes enrichis. Les champs de saisie de texte peuvent être constitués d'une seule ligne (champ texte), de plusieurs lignes (zone de texte) ou, pour un meilleur contrôle des valeurs saisies, une liste de sélection, des cases à cocher ou des boutons radio. Si besoin, CCK peut valider les saisies sur la base d'un ensemble de valeurs autorisées." + +#: content.module:27 +msgid "<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple \"employee\" nodes may contain a <em>nodereference</em> field linking to an \"employer\" node)." +msgstr "<em>Node Reference</em>, qui crée des références personnalisées entre nœuds de Drupal. En ajoutant, par exemple, un champ <em>nodereference</em> et deux types de contenus différents, vous pouvez facilement créer des relations complexes de type parent/enfant entre données (par exemple plusieurs nœuds \"employé\" peuvent présenter un champ <em>nodereference</em> pointant vers un même nœud \"employeur\")." + +#: content.module:28 +msgid "<em>userreference</em>, which creates custom references to your sites' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site's users and posts. To track user involvement in a post beyond Drupal's standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named \"Edited by\" to a content type to store a link to an editor's user account page." +msgstr "<em>User reference</em>, qui crée des références personnalisées vers les comptes des utilisateurs de votre site. En ajoutant un champ <em>userreference</em>, vous pouvez créer des relations complexes entre les utilisateurs de votre site et des publications. Ainsi, pour tracer l'implication d'un utilisateur dans une publication (au delà du champ Drupal standard <em>Écrit par</em>), vous pouvez ajouter à un type de contenu un champ <em>userreference</em> intitulé \"Édité par\" pour enregistrer un lien vers la page du compte utilisateur ayant édité la publication." + +#: content.module:29 +msgid "<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module." +msgstr "<em>Fieldgroup</em>, qui crée des groupes de champs liés. Les groupes de champ peuvent être repliés, et vous pouvez choisir qu'ils soient dépliés ou repliés par défaut. L'ordre des groupes de champs, ainsi que l'ordre des champs au sein d'un groupe, est géré grâce à l'interface par glisser-déposer fournie par le module Content." + +#: content.module:31 +msgid "For more information, see the online handbook entry for <a href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK project page</a>." +msgstr "Pour plus d'informations, reportez-vous à l'entrée de manuel en ligne relative à <a href=\"@handbook-cck\">CCK</a> ou à la <a href=\"@project-cck\">page du projet CCK</a>." + +#: content.module:486 +#: modules/content_multigroup/content_multigroup.module:1422 +msgid "This field is required." +msgstr "Ce champ est obligatoire." + +#: content.module:490 +msgid "!title: !required" +msgstr "!title : !required" + +#: content.module:493 +#: modules/content_multigroup/content_multigroup.module:1434 +msgid "Order" +msgstr "Ordre" + +#: content.module:496 +#: includes/content.admin.inc:171;197;888 +#: modules/content_multigroup/content_multigroup.module:1436 +#: modules/fieldgroup/fieldgroup.module:203 +msgid "Remove" +msgstr "Ôter" + +#: content.module:1868 +msgid "Basic" +msgstr "Basique" + +#: content.module:1871 +#: modules/nodereference/nodereference.module:257 +msgid "Teaser" +msgstr "Résumé" + +#: content.module:1875 +#: modules/nodereference/nodereference.module:252 +msgid "Full node" +msgstr "Nœud complet" + +#: content.module:1881;1884 +msgid "RSS" +msgstr "RSS" + +#: content.module:1894 +msgid "Search" +msgstr "Recherche" + +#: content.module:1897 +msgid "Search Index" +msgstr "Index de recherche" + +#: content.module:1901 +msgid "Search Result" +msgstr "Résultat de recherche" + +#: content.module:2349;2356 +msgid "Node module form." +msgstr "Formulaire du module node." + +#: content.module:2363 +msgid "Language" +msgstr "Langue" + +#: content.module:2364 +msgid "Locale module form." +msgstr "Formulaire du module locale." + +#: content.module:2370 +msgid "Menu settings" +msgstr "Paramètres du menu" + +#: content.module:2371 +msgid "Menu module form." +msgstr "Formulaire du module menu." + +#: content.module:2377 +msgid "Taxonomy" +msgstr "Taxonomie" + +#: content.module:2378 +msgid "Taxonomy module form." +msgstr "Formulaire du module taxonomy." + +#: content.module:2384 +msgid "Book" +msgstr "Livre" + +#: content.module:2385 +msgid "Book module form." +msgstr "Formulaire du module livre (book)." + +#: content.module:2391 +msgid "Poll title" +msgstr "Titre du sondage" + +#: content.module:2392 +msgid "Poll module title." +msgstr "Titre du module sondage (Poll)" + +#: content.module:2396 +msgid "Poll choices" +msgstr "Choix du sondage" + +#: content.module:2397 +msgid "Poll module choices." +msgstr "Choix du module sondage (poll)." + +#: content.module:2401 +msgid "Poll settings" +msgstr "Paramètrage du sondage" + +#: content.module:2402 +msgid "Poll module settings." +msgstr "Paramètres du module sondage (poll)." + +#: content.module:2408 +msgid "File attachments" +msgstr "Fichiers attachés" + +#: content.module:2409 +msgid "Upload module form." +msgstr "Formulaire du module upload." + +#: content.module:600;607;0 +#: includes/content.crud.inc:589;633 +msgid "content" +msgstr "contenu" + +#: content.module:600 +msgid "Updating field type %type with module %module." +msgstr "Mise à jour du type de champ %type avec le module %module." + +#: content.module:607 +msgid "Updating widget type %type with module %module." +msgstr "Mise à jour du type de widget %widget avec le module %module." + +#: content.module:63 +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "Utiliser du code PHP pour le paramétrage des champs (dangereux - à n'autoriser qu'avec précautions)" + +#: content.module:82 +msgid "Fields" +msgstr "Champs" + +#: content.module:104 +msgid "Manage fields" +msgstr "Gérer les champs" + +#: content.module:113 +msgid "Display fields" +msgstr "Afficher les champs" + +#: content.module:144 +msgid "Remove field" +msgstr "Supprimer un champ" + +#: content.install:236 +msgid "Updates for CCK-related modules are not run until the modules are enabled on the <a href=\"@admin-modules-path\">administer modules page</a>. When you enable them, you'll need to return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Les mises à jour des modules liés à CCK ne sont pas exécutées tant que les modules ne sont pas activés sur la <a href=\"@admin-modules-path\">page d'administration des modules</a>. Lorsque vous les activerez, vous devrez retourner sur la page <a href=\"@update-php\">update.php</a> et exécuter les mises à jour restantes." + +#: content.install:239 +msgid "!module.module has updates but cannot be updated because content.module is not enabled.<br />If and when content.module is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "!module.module possède des mises à jour mais ne peut pas être mis à jour car content.module n'est pas activé.<br /> Le cas échéant, lors de l'activation de content.module, vous devrez exécuter à nouveau le script de mise à jour. Vous continuerez à voir ce message jusqu'à ce que le module soit activé et les mises à jour exécutées." + +#: content.install:244 +msgid "!module.module has updates and is available in the modules folder but is not enabled.<br />If and when it is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "!module.module possède des mises à jour et est disponible dans le répertoire des modules, mais n'est pas activé.<br /> Le cas échéant, lorsque vous l'aurez activé, vous devrez ré-exécuter le script de mise à jour. Vous continuerez à voir ce message jusqu'à l'activation du module et l'exécution des mises à jour. " + +#: content.install:251 +msgid "Some updates are still pending. Please return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Des mises à jour sont toujours en attente. Veuillez retourner sur <a href=\"@update-php\">update.php</a> et exécuter les mises à jour restarntes." + +#: content.install:252 +msgid "Some updates are still pending.<br/>Please re-run the update script." +msgstr "Des mises à jour sont toujours en attente.<br/>Veuillez ré-exécuter le script de mise à jour." + +#: (duplicate) content.install:10 +msgid "CCK - No Views integration" +msgstr "CCK - Aucune Intégration aux Vues" + +#: (duplicate) content.install:11 +msgid "CCK integration with Views module requires Views 6.x-2.0-rc2 or greater." +msgstr "L\"intégration de CCK avec le module Views requiert Views 6.x-2.0-rc2 ou une version supérieure." + +#: content.info:0 +#: includes/content.rules.inc:19;200 +#: includes/views/content.views.inc:178;254 +msgid "Content" +msgstr "Contenu" + +#: content.info:0 +msgid "Allows administrators to define new content types." +msgstr "Permet aux administrateurs de définir des nouveaux types de contenu." + +#: content.info:0 +#: modules/content_copy/content_copy.info:0 +#: modules/content_multigroup/content_multigroup.info:0 +#: modules/content_permissions/content_permissions.info:0 +#: modules/fieldgroup/fieldgroup.info:0 +#: modules/nodereference/nodereference.info:0 +#: modules/number/number.info:0 +#: modules/optionwidgets/optionwidgets.info:0 +#: modules/text/text.info:0 +#: modules/userreference/userreference.info:0 +msgid "CCK" +msgstr "CCK" + +#: includes/content.admin.inc:16 +#: modules/content_copy/content_copy_export_form.tpl.php:11 +#: theme/content-admin-field-overview-form.tpl.php:12 +msgid "Name" +msgstr "Nom" + +#: includes/content.admin.inc:16 +#: modules/content_copy/content_copy_export_form.tpl.php:12 +#: theme/content-admin-field-overview-form.tpl.php:13 +msgid "Type" +msgstr "Type" + +#: includes/content.admin.inc:16 +#: modules/fieldgroup/fieldgroup.module:152 +msgid "Description" +msgstr "Description" + +#: includes/content.admin.inc:16 +#: theme/content-admin-field-overview-form.tpl.php:14 +msgid "Operations" +msgstr "Opérations" + +#: includes/content.admin.inc:30 +msgid "edit" +msgstr "éditer" + +#: includes/content.admin.inc:33 +msgid "manage fields" +msgstr "gérer les champs" + +#: includes/content.admin.inc:36 +msgid "delete" +msgstr "supprimer" + +#: includes/content.admin.inc:47 +msgid "No content types available." +msgstr "Aucun type de contenu disponible." + +#: includes/content.admin.inc:54 +msgid "» Add a new content type" +msgstr "» Ajouter un nouveau type de contenu" + +#: includes/content.admin.inc:67;789;984 +msgid "Field name" +msgstr "Nom du champ" + +#: includes/content.admin.inc:67;804;990 +msgid "Field type" +msgstr "Type de champ" + +#: includes/content.admin.inc:67 +msgid "Used in" +msgstr "Utilisé dans" + +#: includes/content.admin.inc:71 +msgid "@field_name (Locked)" +msgstr "@field_name (Verrouillé)" + +#: includes/content.admin.inc:90 +msgid "No fields have been defined for any content type yet." +msgstr "Aucun champ n'est pour l'instant défini sur l'ensemble des types de contenu." + +#: includes/content.admin.inc:106 +msgid "This content type has inactive fields. Inactive fields are not included in lists of available fields until their modules are enabled." +msgstr "Ce type de contenu possède des champs inactifs. Les champs inactifs ne sont pas inclus dans la liste de champs disponibles, jusqu'à l'activation des modules correspondants." + +#: includes/content.admin.inc:108 +msgid "!field (!field_name) is an inactive !field_type field that uses a !widget_type widget." +msgstr "!field (!field_name) est un champ inactif de type !field_type, qui utilise un widget de type !widget_type." + +#: includes/content.admin.inc:170;196 +msgid "Configure" +msgstr "Configurer" + +#: includes/content.admin.inc:181 +msgid "Locked" +msgstr "Verrouillé" + +#: includes/content.admin.inc:237 +msgid "- Select a field type -" +msgstr "- Sélectionnez un type de champ -" + +#: includes/content.admin.inc:238 +msgid "- Select a widget -" +msgstr "- Sélectionnez un widget -" + +#: includes/content.admin.inc:244;285;315;797;978 +#: includes/content.panels.inc:49 +#: includes/views/handlers/content_handler_field.inc:56 +#: modules/content_copy/content_copy_export_form.tpl.php:10 +#: modules/fieldgroup/fieldgroup.module:111 +#: theme/content-admin-display-overview-form.tpl.php:13 +#: theme/content-admin-field-overview-form.tpl.php:10 +msgid "Label" +msgstr "Étiquette" + +#: includes/content.admin.inc:253 +msgid "Field name (a-z, 0-9, _)" +msgstr "Nom du champ (a-z, 0-9, _)" + +#: includes/content.admin.inc:258 +msgid "Type of data to store." +msgstr "Type de données à stocker." + +#: includes/content.admin.inc:263;295 +msgid "Form element to edit the data." +msgstr "Elément du formulaire pour l'édition des données." + +#: includes/content.admin.inc:279 +msgid "- Select an existing field -" +msgstr "- Sélectionnez un champ existant -" + +#: includes/content.admin.inc:290 +msgid "Field to share" +msgstr "Champ à partager" + +#: includes/content.admin.inc:324 +msgid "Group name (a-z, 0-9, _)" +msgstr "Nom du groupe (a-z, 0-9, _)" + +#: includes/content.admin.inc:344;670 +#: modules/fieldgroup/fieldgroup.module:171;335 +msgid "Save" +msgstr "Enregistrer" + +#: includes/content.admin.inc:365 +msgid "Add new field: you need to provide a label." +msgstr "Ajouter un nouveau champ : vous devez fournir une étiquette." + +#: includes/content.admin.inc:370 +msgid "Add new field: you need to provide a field name." +msgstr "Ajouter un nouveau champ : vous devez fournir un nom de champ." + +#: includes/content.admin.inc:384 +msgid "Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Ajouter un nouveau champ : le nom de champ %field_name n'est pas valide. Le nom doit seulement contenir des lettre minuscules non accentuées, des nombres, et des underscores. " + +#: includes/content.admin.inc:387 +msgid "Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix." +msgstr "Ajouter un nouveau champ : le nom de champ %field_name est trop long. Le nom est limité à 32 caractères, en comptant le préfixe 'field_'." + +#: includes/content.admin.inc:391 +msgid "Add new field: the name 'field_instance' is a reserved name." +msgstr "Ajouter un nouveau champ : le nom 'field_instance' est un nom réservé." + +#: includes/content.admin.inc:403 +msgid "Add new field: the field name %field_name already exists." +msgstr "Ajouter un nouveau champ : le nom du champ %field_name existe déjà." + +#: includes/content.admin.inc:409 +msgid "Add new field: you need to select a field type." +msgstr "Ajouter un nouveau champ : vous devez sélectionner un type de champ." + +#: includes/content.admin.inc:414 +msgid "Add new field: you need to select a widget." +msgstr "Ajouter un nouveau champ : vous devez sélectionner un widget." + +#: includes/content.admin.inc:420 +msgid "Add new field: invalid widget." +msgstr "Ajouter un nouveau champ : widget non valide." + +#: includes/content.admin.inc:441 +msgid "Add existing field: you need to provide a label." +msgstr "Ajouter un champ existant : vous devez fournir une étiquette." + +#: includes/content.admin.inc:446 +msgid "Add existing field: you need to select a field." +msgstr "Ajouter un champ existant : vous devez sélectionner un champ." + +#: includes/content.admin.inc:451 +msgid "Add existing field: you need to select a widget." +msgstr "Ajouter un champ existant: vous devez sélectionner un widget." + +#: includes/content.admin.inc:457 +msgid "Add existing field: invalid widget." +msgstr "Ajouter un champ existant : widget non valide." + +#: includes/content.admin.inc:506 +msgid "There was a problem creating field %label." +msgstr "Un problème est survenu à la création du champ '%label'." + +#: includes/content.admin.inc:518 +msgid "The field %label cannot be added to a content type because it is locked." +msgstr "Le champ %label n'a pas pu être ajouté au type de contenu car il est verrouillé." + +#: includes/content.admin.inc:528 +msgid "There was a problem adding field %label." +msgstr "Un problème est survenu lors de l'ajout du champ '%label'." + +#: includes/content.admin.inc:571 +msgid "There are no fields configured for this content type. You can add new fields on the <a href=\"@link\">Manage fields</a> page." +msgstr "Il n'y a aucun champ configuré pour ce type de contenu. Vous pouvez ajouter de nouveaux champs sur la page <a href=\"@link\">Gérer les champs</a>." + +#: includes/content.admin.inc:578;626 +#: includes/content.panels.inc:53 +#: modules/content_multigroup/content_multigroup.module:365 +msgid "Above" +msgstr "Au dessus" + +#: includes/content.admin.inc:579 +#: includes/content.panels.inc:54 +msgid "Inline" +msgstr "Sur la même ligne" + +#: includes/content.admin.inc:580;607;627;635 +#: modules/content_multigroup/content_multigroup.module:366 +msgid "<Hidden>" +msgstr "<Caché>" + +#: includes/content.admin.inc:618;661 +msgid "Include" +msgstr "Inclure" + +#: includes/content.admin.inc:618;661 +#: theme/content-admin-display-overview-form.tpl.php:17 +msgid "Exclude" +msgstr "Exclure" + +#: includes/content.admin.inc:630 +msgid "no styling" +msgstr "aucune mise en forme" + +#: includes/content.admin.inc:631 +msgid "simple" +msgstr "simple" + +#: includes/content.admin.inc:632 +msgid "fieldset" +msgstr "groupe de champs" + +#: includes/content.admin.inc:633 +msgid "fieldset - collapsible" +msgstr "groupe de champs - repliable" + +#: includes/content.admin.inc:634 +msgid "fieldset - collapsed" +msgstr "groupe de champs - replié" + +#: includes/content.admin.inc:690 +msgid "Your settings have been saved." +msgstr "Vos paramètres ont été enregistrés." + +#: includes/content.admin.inc:760 +msgid "@type: @field (@label)" +msgstr "@type : @field (@label)" + +#: includes/content.admin.inc:786 +msgid "Edit basic information" +msgstr "Éditer les informations de base" + +#: includes/content.admin.inc:792 +msgid "The machine-readable name of the field. This name cannot be changed." +msgstr "Le nom lisible par une machine du champ. Ce nom ne peut être changé." + +#: includes/content.admin.inc:800 +msgid "A human-readable name to be used as the label for this field in the %type content type." +msgstr "Nom lisible par une personne, destiné à servir d'étiquette pour ce champ au sein du type de contenu '%type'." + +#: includes/content.admin.inc:807 +msgid "The type of data you would like to store in the database with this field. This option cannot be changed." +msgstr "Type de données que vous souhaitez enregistrer, par le biais de ce champ, dans la base de données. Cette option ne peut être modifiée." + +#: includes/content.admin.inc:812;996 +msgid "Widget type" +msgstr "Type de widget" + +#: includes/content.admin.inc:816 +msgid "The type of form element you would like to present to the user when creating this field in the %type content type." +msgstr "Type d'élément de formulaire que vous souhaitez présenter à l'utilisateur lorsqu'il renseigne ce champ dans le type de contenu '%type'." + +#: includes/content.admin.inc:826 +#: includes/content.rules.inc:66 +msgid "Continue" +msgstr "Continuer" + +#: includes/content.admin.inc:854 +msgid "Updated basic settings for field %label." +msgstr "Les paramètres basiques du champ %label ont été mis à jour." + +#: includes/content.admin.inc:858 +msgid "There was a problem updating the basic settings for field %label." +msgstr "Un problème a été rencontré lors de la mise à jour des paramètres basiques du champ %label." + +#: includes/content.admin.inc:885 +msgid "Are you sure you want to remove the field %field?" +msgstr "Êtes-vous certain de vouloir enlever le champ '%field' ?" + +#: includes/content.admin.inc:887 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Si vous avez encore du contenu dans ce champ, il sera perdu. Cette action est irréversible." + +#: includes/content.admin.inc:888 +#: modules/fieldgroup/fieldgroup.module:203 +msgid "Cancel" +msgstr "Annuler" + +#: includes/content.admin.inc:894 +msgid "This field is <strong>locked</strong> and cannot be removed." +msgstr "Ce champ est <strong>verrouillé</strong> et ne peut être supprimé." + +#: includes/content.admin.inc:915 +msgid "Removed field %field from %type." +msgstr "Le champ '%field' de '%type' a été enlevé." + +#: includes/content.admin.inc:920 +msgid "There was a problem deleting %field from %type." +msgstr "Un problème est survenu à la suppression du champ '%field' du type '%type'." + +#: includes/content.admin.inc:939 +msgid "The field %field is locked and cannot be edited." +msgstr "Le champ %field est verouillé et ne peut être édité." + +#: includes/content.admin.inc:973 +msgid "%type basic information" +msgstr "Informations de base pour '%type'" + +#: includes/content.admin.inc:1003;1182 +msgid "Change basic information" +msgstr "Modifier les informations de base" + +#: includes/content.admin.inc:1009 +msgid "%type settings" +msgstr "Paramètres de '%type'" + +#: includes/content.admin.inc:1010 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Ces paramètres ne s'applique qu'au champ '%field' tel qu'il apparaît dans le type contenu '%type'." + +#: includes/content.admin.inc:1024 +#: modules/fieldgroup/fieldgroup.module:139 +msgid "Help text" +msgstr "Texte d'aide" + +#: includes/content.admin.inc:1027 +msgid "Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags" +msgstr "Instructions à présenter à l'utilisateur sous ce champ, dans le formulaire d'édition.<br />Balises HTML autorisées : @tags" + +#: includes/content.admin.inc:1053 +msgid "Default value" +msgstr "Valeur par défaut" + +#: includes/content.admin.inc:1074 +#: modules/number/number.module:120 +#: modules/text/text.module:85 +msgid "PHP code" +msgstr "Code PHP" + +#: includes/content.admin.inc:1083;1238 +#: includes/content.rules.inc:93 +msgid "'@column' => value for @column" +msgstr "'@column' => valeur de @column" + +#: includes/content.admin.inc:1085;1240 +#: includes/content.rules.inc:95 +msgid "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" +msgstr "" +"return array(\n" +" 0 => array(@columns),\n" +" // Vous voudrez vous arrêter là dans la plupart des cas. Fournir plus de valeurs\n" +" // si vous souhaitez que votre 'valeur par défaut' ait des valeurs multiples :\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" + +#: includes/content.admin.inc:1089;1102 +#: includes/content.rules.inc:99 +#: modules/number/number.module:127;136 +#: modules/text/text.module:92;101 +msgid "Code" +msgstr "Code" + +#: includes/content.admin.inc:1093 +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>To figure out the expected format, you can use the <em>devel load</em> tab provided by <a href=\"@link_devel\">devel module</a> on a %type content page." +msgstr "Usage avancé seulement : code PHP retournant une valeur par défaut. Ne doit pas contenir les délimiteurs <?php ?>. Si ce champ est rempli, la valeur retournée par ce code écrasera toute valeur spécifiée ci-dessus. Format attendu : <pre>!sample</pre>. Pour vous faire une idée du format attendu, vous pouvez utiliser l'onglet <em>devel load</em> fourni par <a href=\"@link_devel\">le module devel</a> sur une page de contenu de type %type." + +#: includes/content.admin.inc:1103 +#: modules/number/number.module:137 +#: modules/text/text.module:102 +msgid "<none>" +msgstr "<aucun>" + +#: includes/content.admin.inc:1104 +#: modules/number/number.module:138 +#: modules/text/text.module:103 +msgid "You're not allowed to input PHP code." +msgstr "Vous n'êtes pas autorisé à saisir du code PHP." + +#: includes/content.admin.inc:1104 +msgid "This PHP code was set by an administrator and will override any value specified above." +msgstr "Ce code PHP a été inséré par un administrateur et supplantera toute valeur spécifiée ci-dessus." + +#: includes/content.admin.inc:1111 +msgid "Global settings" +msgstr "Paramètres globaux" + +#: includes/content.admin.inc:1112 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Ces paramètres s'appliquent au champ '%field' dans tous les types de contenu où il apparaît." + +#: includes/content.admin.inc:1116 +#: modules/content_multigroup/content_multigroup.module:483 +msgid "Required" +msgstr "Obligatoire" + +#: includes/content.admin.inc:1119 +msgid "Maximum number of values users can enter for this field." +msgstr "Le nombre maximum de valeurs qu'un utilisateur peut entrer pour ce champ." + +#: includes/content.admin.inc:1121 +msgid "'Unlimited' will provide an 'Add more' button so the users can add as many values as they like." +msgstr "'Illimité' fournira un bouton 'Ajouter plus' pour que les utilisateurs puissent ajouter autant de valeurs qu'ils le souhaitent." + +#: includes/content.admin.inc:1123 +msgid "Warning! Changing this setting after data has been created could result in the loss of data!" +msgstr "Attention ! Changer ce paramètre alors que des données ont déjà été créées peut conduire à perdre des données !" + +#: includes/content.admin.inc:1126 +msgid "Number of values" +msgstr "Nombre de valeurs" + +#: includes/content.admin.inc:1127 +#: modules/content_multigroup/content_multigroup.module:85 +msgid "Unlimited" +msgstr "Illimité" + +#: includes/content.admin.inc:1144 +#: modules/content_copy/content_copy.module:251 +msgid "Save field settings" +msgstr "Enregistrer les paramètres du champ" + +#: includes/content.admin.inc:1242 +msgid "The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value" +msgstr "Le code PHP de valeur par défaut a renvoyé une valeur incorrecte.<br/>Format attendu : <pre>!sample</pre> Valeur renvoyée : @value" + +#: includes/content.admin.inc:1281 +msgid "The PHP code for 'default value' returned @value, which is invalid." +msgstr "Le code PHP pour la 'valeur par défaut' a retourné @value, qui n'est pas valide." + +#: includes/content.admin.inc:1285 +msgid "The default value is invalid." +msgstr "La valeur par défaut est invalide." + +#: includes/content.admin.inc:1309 +msgid "Added field %label." +msgstr "Le champ '%label' a été ajouté." + +#: includes/content.admin.inc:1313 +msgid "Saved field %label." +msgstr "Champ '%label' enregistré." + +#: includes/content.admin.inc:1662 +msgid "Processing" +msgstr "Exécution" + +#: includes/content.admin.inc:1663 +msgid "The update has encountered an error." +msgstr "La mise à jour a échoué." + +#: includes/content.admin.inc:1677 +msgid "The database has been altered and data has been migrated or deleted." +msgstr "La base de données a été modifiée et des données ont été déplacées ou supprimées." + +#: includes/content.admin.inc:1680 +msgid "An error occurred and database alteration did not complete." +msgstr "Une erreur est survenue et a interrompu la modification de la base de données." + +#: includes/content.admin.inc:1783 +msgid "Processing %title" +msgstr "'%title' en cours de traitement" + +#: includes/content.admin.inc:1849 +msgid "%name must be an integer." +msgstr "%name doit être un entier." + +#: includes/content.admin.inc:1859 +msgid "%name must be a positive integer." +msgstr "%name doit être un entier positif." + +#: includes/content.admin.inc:1869 +msgid "%name must be a number." +msgstr "%name doit être un nombre." + +#: includes/content.admin.inc:1681 +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "1 élément traité avec succès :" +msgstr[1] "@count éléments traités avec succès :" + +#: includes/content.crud.inc:589 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "La table de champs a été renommée de '%old_name' à '%new_name' et les instances des champs ont été mises à jour." + +#: includes/content.crud.inc:633 +msgid "The content fields table %name has been deleted." +msgstr "La table de champs '%name' a été supprimée." + +#: includes/content.node_form.inc:240 +msgid "Add another item" +msgstr "Ajouter un autre élément" + +#: includes/content.panels.inc:21;35 +msgid "Content field" +msgstr "Contenu du champ" + +#: includes/content.panels.inc:38 +msgid "A content field from the referenced node." +msgstr "Un champ de contenu du node référencé." + +#: includes/content.panels.inc:39 +#: modules/fieldgroup/fieldgroup.panels.inc:31 +msgid "Node" +msgstr "Noeud" + +#: includes/content.panels.inc:40 +#: modules/fieldgroup/fieldgroup.panels.inc:32 +msgid "Node context" +msgstr "Contexte du noeud" + +#: includes/content.panels.inc:52 +msgid "Block title" +msgstr "Titre du bloc" + +#: includes/content.panels.inc:55 +msgid "Hidden" +msgstr "Caché" + +#: includes/content.panels.inc:57 +msgid "Configure how the label is going to be displayed." +msgstr "Configurer la manière dont l'étiquette est affichée." + +#: includes/content.panels.inc:73 +msgid "Field / Formatter" +msgstr "Champ / Formateur" + +#: includes/content.panels.inc:76 +msgid "Select a field and formatter." +msgstr "Sélectionner un champ et un formateur." + +#: includes/content.panels.inc:92 +msgid "\"@s\" field @name" +msgstr "\"@s\" champ @name" + +#: includes/content.rules.inc:15 +msgid "Populate a field" +msgstr "Remplir un champ" + +#: includes/content.rules.inc:23;212 +msgid "You should make sure that the used field exists in the given content type." +msgstr "Vous devez vous assurer que le champ existe pour le type de contenu donné." + +#: includes/content.rules.inc:53;266 +#: modules/nodereference/nodereference.rules.inc:45 +#: modules/userreference/userreference.rules.inc:47 +#: theme/content-admin-display-overview-form.tpl.php:11 +msgid "Field" +msgstr "Champ" + +#: includes/content.rules.inc:56 +msgid "Select the machine-name of the field." +msgstr "Sélectionnez le nom-machine du champ." + +#: includes/content.rules.inc:84 +msgid "Advanced: Specify the fields value with PHP code" +msgstr "Avancé : Préciser les valeurs des champs avec du code PHP" + +#: includes/content.rules.inc:102 +msgid "Advanced usage only: PHP code that returns the value to set. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>Using <a href=\"@link_devel\">devel.module's</a> 'devel load' tab on a content page might help you figure out the expected format." +msgstr "Usage avancé seulement : code PHP retournant la valeur à définir. Ne doit pas contenir les délimiteurs <?php ?>. Si ce champ est rempli, la valeur retournée par ce code écrasera toute valeur spécifiée ci-dessus. Format attendu : <pre>!sample</pre>. Pour vous faire une idée du format attendu, vous pouvez utiliser l'onglet <em>devel load</em> fourni par <a href=\"@link_devel\">le module devel</a> sur une page de contenu de type %type." + +#: includes/content.rules.inc:130 +msgid "You have to return the default value in the expected format." +msgstr "Vous devez retourner la valeur par défaut dans le format attendu." + +#: includes/content.rules.inc:181 +msgid "Populate @node's field '@field'" +msgstr "Remplir le champ '@field' de @node" + +#: includes/content.rules.inc:198 +msgid "Field has value" +msgstr "Le champ possède une valeur" + +#: includes/content.rules.inc:203 +msgid "You should make sure that the used field exists in the given content type. The condition returns TRUE, if the selected field has the given value." +msgstr "Vous devez vous assurer que le champ utilisé existe dans le type de contenu donné. La condition retourne TRUE, si le champ sélectionné possède la valeur donnée." + +#: includes/content.rules.inc:207 +msgid "Field has changed" +msgstr "Le champ a été modifié" + +#: includes/content.rules.inc:209 +msgid "Content containing changes" +msgstr "Contenu contenant des modifications" + +#: includes/content.rules.inc:210 +msgid "Content not containing changes" +msgstr "Contenu ne contenant pas de modification" + +#: includes/content.rules.inc:249 +msgid "@node's field '@field' has value" +msgstr "Le champ '@field' de @node possède une valeur" + +#: includes/content.rules.inc:269 +msgid "Select the machine-name of the field to look at." +msgstr "Sélectionnez le nom-machine du champ à voir." + +#: includes/content.rules.inc:275 +msgid "@node's field '@field' has been changed" +msgstr "Le champ '@field' de @node a été modifié" + +#: includes/content.token.inc:12;15 +msgid "Token" +msgstr "Jeton (Token)" + +#: includes/content.token.inc:81 +msgid "Referenced node ID" +msgstr "Identifiant du nœud référencé" + +#: includes/content.token.inc:82 +msgid "Referenced node title" +msgstr "Titre du nœud référencé" + +#: includes/content.token.inc:83 +msgid "Referenced node unfiltered title. WARNING - raw user input." +msgstr "Titre non filtré du noeud référencé. ATTENTION - saisie brute utilisateur." + +#: includes/content.token.inc:84 +msgid "Formatted html link to the referenced node." +msgstr "Lien html formaté vers le noeud référencé." + +#: includes/content.token.inc:85 +msgid "Relative path alias to the referenced node." +msgstr "Alias de chemin relatif vers le noeud référencé." + +#: includes/content.token.inc:86 +msgid "Absolute path alias to the referenced node." +msgstr "Alias de chemin absolu vers le noeud référencé." + +#: includes/content.token.inc:114 +msgid "Raw number value" +msgstr "Valeur numérique brute" + +#: includes/content.token.inc:115 +msgid "Formatted number value" +msgstr "Valeur numérique mise en forme" + +#: includes/content.token.inc:138 +msgid "Raw, unfiltered text" +msgstr "Texte brut, non filtré" + +#: includes/content.token.inc:139 +msgid "Formatted and filtered text" +msgstr "Texte filtré et mis en forme" + +#: includes/content.token.inc:161 +msgid "Referenced user ID" +msgstr "Identifiant de l'utilisateur référencé" + +#: includes/content.token.inc:162 +msgid "Referenced user name" +msgstr "Nom de l'utilisateur référencé" + +#: includes/content.token.inc:163 +msgid "Formatted HTML link to referenced user" +msgstr "Lien HTML mis en forme vers l'utilisateur référencé" + +#: includes/content.token.inc:164 +msgid "Relative path alias to the referenced user." +msgstr "Alias de chemin relatif vers l'utilisateur référencé." + +#: includes/content.token.inc:165 +msgid "Absolute path alias to the referenced user." +msgstr "Alias de chemin absolu vers l'utilisateur référencé." + +#: includes/views/content.views.inc:245;261 +msgid "@label (!name)" +msgstr "@label (!name)" + +#: includes/views/content.views.inc:249 +msgid "@label (!name) - !column" +msgstr "@label (!name) - !column" + +#: includes/views/content.views.inc:250 +msgid "@label-truncated - !column" +msgstr "@label-truncated - !column" + +#: includes/views/content.views.inc:257 +msgid "Appears in: @types" +msgstr "Apparaît dans : @types" + +#: includes/views/content.views.inc:279 +msgid "<No value>" +msgstr "<Aucune valeur>" + +#: includes/views/handlers/content_handler_field.inc:59 +msgid "None" +msgstr "Aucun" + +#: includes/views/handlers/content_handler_field.inc:60 +msgid "Widget label (@label)" +msgstr "Étiquette du widget (@label)" + +#: includes/views/handlers/content_handler_field.inc:61 +msgid "Custom" +msgstr "Personnalisé" + +#: includes/views/handlers/content_handler_field.inc:67 +msgid "Custom label" +msgstr "Étiquette personnalisée" + +#: includes/views/handlers/content_handler_field.inc:83 +msgid "Format" +msgstr "Format" + +#: includes/views/handlers/content_handler_field_multiple.inc:58 +msgid "Group multiple values" +msgstr "Grouper plusieurs valeurs" + +#: includes/views/handlers/content_handler_field_multiple.inc:61 +msgid "If unchecked, each item in the field will create a new row, which may appear to cause duplicates. This setting is not compatible with click-sorting in table displays." +msgstr "Si non coché, chaque élément du champ créera une nouvelle ligne, ce qui pourrait apparemment entraîner des doublons. Ce paramètre n'est pas compatible avec le tri par clic dans l'affichage du tableau. " + +#: includes/views/handlers/content_handler_field_multiple.inc:65 +msgid "Show @count value(s)" +msgstr "Afficher @count valeur(s)" + +#: includes/views/handlers/content_handler_field_multiple.inc:76 +msgid "starting from @count" +msgstr "en commençant à @count" + +#: includes/views/handlers/content_handler_field_multiple.inc:87 +msgid "Reversed (start from last values)" +msgstr "Inversé (commencer à partir des dernières valeurs)" + +#: includes/views/handlers/content_handler_relationship.inc:40 +#: includes/views/handlers/content_handler_sort.inc:41 +msgid "All" +msgstr "Tous / Toutes" + +#: includes/views/handlers/content_handler_relationship.inc:48 +#: includes/views/handlers/content_handler_sort.inc:49 +msgid "Delta" +msgstr "Delta" + +#: includes/views/handlers/content_handler_relationship.inc:49 +msgid "The delta allows you to select which item in a multiple value field to key the relationship off of. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "Le delta vous permet de sélectionner quel élément d'un champ à valeur multiple sera la clé de la relation. Sélectionnez \"1\" pour utiliser le premier élément, \"2\" pour le second et ainsi de suite. Si vous sélectionnez \"Tous\", chaque élément du champ créera une nouvelle ligne, ce qui pourrait causer des doublons." + +#: includes/views/handlers/content_handler_sort.inc:50 +msgid "The delta allows you to select which item in a multiple value field will be used for sorting. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "Le delta vous permet de sélectionner quel élément d'un champ à valeur multiple sera utilisé pour les tris. Sélectionnez \"1\" pour utiliser le premier élément, \"2\" pour le second et ainsi de suite. Si vous sélectionnez \"Tous\", chaque élément du champ créera une nouvelle ligne, ce qui pourrait causer des doublons." + +#: modules/content_copy/content_copy_export_form.tpl.php:9 +#: modules/content_copy/content_copy.module:191;38 +msgid "Export" +msgstr "Exporter" + +#: modules/content_copy/content_copy.module:97 +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "Ce formulaire traitera un type de contenu et un ou plusieurs champs de ce type, pour en exporter les paramètres. Le code d'export ainsi généré peut être copié et collé dans la page d'import, vers la base de données courante ou vers une autre base de données. L'opération d'import ajoutera les champs à un type de contenu existant ou créera un nouveau type de contenu intégrant les champs sélectionnés." + +#: modules/content_copy/content_copy.module:103 +msgid "Types" +msgstr "Types" + +#: modules/content_copy/content_copy.module:107 +msgid "Select the content type to export." +msgstr "Sélectionner le type de contenu à exporter." + +#: modules/content_copy/content_copy.module:175 +msgid "Export data" +msgstr "Données exportée" + +#: modules/content_copy/content_copy.module:180 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Copiez le texte exporté et collez-le dans le type de contenu de votre choix, à l'aide de la fonction d'import." + +#: modules/content_copy/content_copy.module:184 +msgid "Content types" +msgstr "Types de contenu" + +#: modules/content_copy/content_copy.module:303 +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "Ce formulaire importera les définitions de champs exportées depuis un autre type de contenu, ou une autre base de données.<br/> Veuillez noter que les champs ne peuvent pas être dupliqués au sein d'un même type de contenu, si bien que les champs importés ne seront ajoutés que si ils n'existent pas déjà dans le type sélectionné." + +#: modules/content_copy/content_copy.module:306 +msgid "<Create>" +msgstr "<Créer>" + +#: modules/content_copy/content_copy.module:308 +msgid "Content type" +msgstr "Type de contenu" + +#: modules/content_copy/content_copy.module:309 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Séléctionnez le type de contenu dans lequel importer ces champs.<br />Sélectionnez <Créer> pour créer un nouveau type de contenu qui contiendra ces champs." + +#: modules/content_copy/content_copy.module:314 +msgid "Import data" +msgstr "Données à importer" + +#: modules/content_copy/content_copy.module:316 +msgid "Paste the text created by a content export into this field." +msgstr "Collez dans ce champ le texte créé par un export de contenu." + +#: modules/content_copy/content_copy.module:320;46 +msgid "Import" +msgstr "Importer" + +#: modules/content_copy/content_copy.module:328 +msgid "A file has been pre-loaded for import." +msgstr "Un fichier a été préchargé pour l'import." + +#: modules/content_copy/content_copy.module:354 +msgid "The import data is not valid import text." +msgstr "Les données d'import ne sont valides." + +#: modules/content_copy/content_copy.module:403 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "Les modules suivants doivent être activés pour que l'import fonctionne : '%modules'." + +#: modules/content_copy/content_copy.module:411 +msgid "The content type %type already exists in this database." +msgstr "Le type de contenu '%type' existe déjà dans cette base de données." + +#: modules/content_copy/content_copy.module:418 +msgid "Exiting. No import performed." +msgstr "Abandon. L'import n'a pas été réalisé." + +#: modules/content_copy/content_copy.module:442 +msgid "An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Une erreur s'est produite lors de l'ajout du nouveau type de contenu %type.<br> Veuillez vérifier les erreurs affichées pour plus de détails." + +#: modules/content_copy/content_copy.module:467 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "Le champ importé '%field_label' (%field_name) n'a pas été ajouté à '%type' car ce champ existe déjà." + +#: modules/content_copy/content_copy.module:476 +msgid "The field %field_label (%field_name) was added to the content type %type." +msgstr "Le champ importé '%field_label' (%field_name) a été ajouté au type de contenu '%type'." + +#: modules/content_copy/content_copy.module:581 +msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'." +msgstr "Une erreur s'est produite lors de l'export des données des 'paramètres d'affichage' du champ %field_name.<br/> L'erreur de base de données est : '%db_err'." + +#: modules/content_copy/content_copy.module:0 +msgid "content_copy" +msgstr "content_copy" + +#: modules/content_copy/content_copy.info:0 +msgid "Content Copy" +msgstr "Content Copy" + +#: modules/content_copy/content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "Permet d'importer et d'exporter des définitions de champs." + +#: modules/content_multigroup/content_multigroup.module:12 +msgid "The fields in a Standard group are independent of each other and each can have either single or multiple values. The fields in a Multigroup are treated as a repeating collection of single value fields." +msgstr "Les champs d'un groupe Standard sont indépendants les uns des autres, et chacun peut soit avoir une valeur unique, soit des valeurs multiples. Les champs d'un Multigroupe sont traités comme une ensemble répétable de champs à valeurs uniques." + +#: modules/content_multigroup/content_multigroup.module:65;135 +msgid "Multigroup" +msgstr "Multigroupe" + +#: modules/content_multigroup/content_multigroup.module:134 +msgid "Standard" +msgstr "Standard" + +#: modules/content_multigroup/content_multigroup.module:138 +msgid "Type of group." +msgstr "Type de groupe." + +#: modules/content_multigroup/content_multigroup.module:215 +msgid "The field %field has been updated to use %multiple values, to match the multiple value setting of the Multigroup %group." +msgstr "Le champ %field a été mis à jour pour l'utilisation de valeurs %multiple, afin de correspondre au paramètre de valeur multipe du Multigroup %group." + +#: modules/content_multigroup/content_multigroup.module:248 +msgid "This change is not allowed. The field %field already has %multiple values in the database but the group %group only allows %group_max. Making this change would result in the loss of data." +msgstr "Cette modification n'est pas autorisée. Le champ %field possède déjà des valeurs multiples dans la base de données, mais le groupe %group en autorise seulement %group_max. Effectuer cette modification pourrait entraîner la perte de données. " + +#: modules/content_multigroup/content_multigroup.module:272 +msgid "This change is not allowed. The field %field handles multiple values differently than the Content module. Making this change could result in the loss of data." +msgstr "Cette modification n'est pas autorisée. Le champ %field manipule les valeurs multiples différemment du module Content. Effectuer cette modification pourrait entraîner la perte de données. " + +#: modules/content_multigroup/content_multigroup.module:287 +msgid "You are moving the field %field into a Multigroup." +msgstr "Vous êtes en train d'inclure le champ %field dans un Multigroupe" + +#: modules/content_multigroup/content_multigroup.module:320 +msgid "This change is not allowed. The field %field already has data created and uses a widget that stores data differently in a Standard group than in a Multigroup. Making this change could result in the loss of data." +msgstr "Cette modification n'est pas autorisée. Le champ %field possède déjà des données créées, et utilise un widget qui stocke les données différemment dans un groupe Standard que dans un Multigroupe. Effectuer ce changement pourrait entraîner la perte de données." + +#: modules/content_multigroup/content_multigroup.module:334 +msgid "You are moving the field %field out of a Multigroup." +msgstr "Vous êtes en train de retirer le champ %field d'un Multigroupe" + +#: modules/content_multigroup/content_multigroup.module:369 +msgid "Simple" +msgstr "Simple" + +#: modules/content_multigroup/content_multigroup.module:370 +msgid "Fieldset" +msgstr "Groupe de champs" + +#: modules/content_multigroup/content_multigroup.module:371 +msgid "Horizontal line" +msgstr "Ligne horizontale" + +#: modules/content_multigroup/content_multigroup.module:372 +msgid "Table - Single column" +msgstr "Tableau - Colonne unique" + +#: modules/content_multigroup/content_multigroup.module:373 +msgid "Table - Multiple columns" +msgstr "Tableau - Colonnes multiples" + +#: modules/content_multigroup/content_multigroup.module:384 +msgid "[Subgroup format]" +msgstr "[Format du sous-groupe]" + +#: modules/content_multigroup/content_multigroup.module:461 +msgid "Multigroup settings" +msgstr "Paramètres multigroupe" + +#: modules/content_multigroup/content_multigroup.module:476 +msgid "Multiple columns" +msgstr "Colonnes multiples" + +#: modules/content_multigroup/content_multigroup.module:478 +msgid "Enable this option to render each field on a separate column on the node edit form." +msgstr "Activez cette option pour rendre chaque champs dans une colonne disctincte sur le formulaire d'édition de noeud." + +#: modules/content_multigroup/content_multigroup.module:485 +msgid "Enable this option to require a minimum of one collection of fields in this Multigroup." +msgstr "Activez cette option pour rendre obligatoire un minimum d'une collection de champs dans ce Multigroupe." + +#: modules/content_multigroup/content_multigroup.module:488 +msgid "Number of times to repeat the collection of Multigroup fields." +msgstr "Nombre de fois où répéter l'ensemble Multigroupe de champs." + +#: modules/content_multigroup/content_multigroup.module:489 +msgid "'Unlimited' will provide an 'Add more' button so the users can add items as many times as they like." +msgstr "'Illimité' fournira un bouton 'Ajouter plus' pour que les utilisateurs puissent ajouter des éléments autant de fois qu'ils le souhaitent." + +#: modules/content_multigroup/content_multigroup.module:490 +msgid "All fields in this group will automatically be set to allow this number of values." +msgstr "Tous les champs de ce groupe seront automatiquement paramétrés pour autoriser ce nombre de valeurs." + +#: modules/content_multigroup/content_multigroup.module:495 +msgid "Number of repeats" +msgstr "Nombre de répétitions" + +#: modules/content_multigroup/content_multigroup.module:503 +msgid "Labels" +msgstr "Etiquettes" + +#: modules/content_multigroup/content_multigroup.module:504 +msgid "Labels for each subgroup of fields. Labels can be hidden or shown in various contexts using the 'Display fields' screen." +msgstr "Etiquettes pour chaque sous-groupe de champs. Les étiquettes peuvent être cachées ou affichées dans des contextes divers en utilisant l'écran 'Afficher les champs'." + +#: modules/content_multigroup/content_multigroup.module:512 +msgid "Subgroup %number label" +msgstr "Etiquette du sous-groupe %number" + +#: modules/content_multigroup/content_multigroup.module:539 +msgid "The field %field in this group already has %multiple values in the database. To prevent the loss of data you cannot set the number of Multigroup values to less than this." +msgstr "Le champ %field dans ce groupe possède déjà %multiple valeurs dans la base de données. Pour éviter la perte de données, vous ne pouvez définir le nombre de valeurs du Multigroupe à une valeur inférieure." + +#: modules/content_multigroup/content_multigroup.module:932 +msgid "!name field is required in group @group." +msgstr "Le champ !name est obligatoire dans le groupe @group." + +#: modules/content_multigroup/content_multigroup.module:946 +msgid "Group @name requires one collection of fields minimum." +msgstr "Le groupe @name requiert au minimum un groupe de champs." + +#: modules/content_multigroup/content_multigroup.module:1145 +msgid "Add more values" +msgstr "Ajouter plus de valeurs" + +#: modules/content_multigroup/content_multigroup.module:0 +msgid "content_multigroup" +msgstr "content_multigroup" + +#: modules/content_multigroup/content_multigroup.info:0 +msgid "Content Multigroup" +msgstr "Contenu Multigroupe" + +#: modules/content_multigroup/content_multigroup.info:0 +msgid "Combine multiple CCK fields into repeating field collections that work in unison." +msgstr "Combinez de multiples champs CCK au sein de collections de champs qui fonctionnent à l'unisson." + +#: modules/content_permissions/content_permissions.module:10 +msgid "edit " +msgstr "éditer" + +#: modules/content_permissions/content_permissions.module:10;11 +msgid "field_name" +msgstr "field_name" + +#: modules/content_permissions/content_permissions.module:11 +msgid "view " +msgstr "voir" + +#: modules/content_permissions/content_permissions.module:0 +msgid "content_permissions" +msgstr "content_permissions" + +#: modules/content_permissions/content_permissions.install:9 +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "Veuillez <a href=\"!url\">configurer vos permissions sur les champs</a> immédiatement. Tous les champs sont inaccessibles par défaut." + +#: modules/content_permissions/content_permissions.info:0 +msgid "Content Permissions" +msgstr "Permissions sur les Contenus" + +#: modules/content_permissions/content_permissions.info:0 +msgid "Set field-level permissions for CCK fields." +msgstr "Définit un niveau de permission par champ pour les champs CCK." + +#: modules/fieldgroup/fieldgroup.panels.inc:10;27 +msgid "Content fieldgroup" +msgstr "Contenu du groupe de champ" + +#: modules/fieldgroup/fieldgroup.panels.inc:30 +msgid "All fields from a fieldgroup on the referenced node." +msgstr "Tous les champs d'un groupe de champs sur le node référencé." + +#: modules/fieldgroup/fieldgroup.panels.inc:91 +msgid "@group_label (@group_type_name)" +msgstr "@group_label (@group_type_name)" + +#: modules/fieldgroup/fieldgroup.panels.inc:102 +#: modules/fieldgroup/fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "Fieldgroup" + +#: modules/fieldgroup/fieldgroup.panels.inc:112 +msgid "Text to display if group has no data. Note that title will not display unless overridden." +msgstr "Texte à afficher si un groupe n'a pas de données. Notez que le titre ne s'affichera pas sauf s'il est surclassé." + +#: modules/fieldgroup/fieldgroup.panels.inc:128 +msgid "\"@s\" fieldgroup @name" +msgstr "\"@s\" groupe de champs @name" + +#: modules/fieldgroup/fieldgroup.module:124 +msgid "Form settings" +msgstr "Paramètres du formulaire" + +#: modules/fieldgroup/fieldgroup.module:125 +msgid "These settings apply to the group in the node editing form." +msgstr "Ces paramètres s'appliquent au groupe dans le formulaire d'édition de nœud." + +#: modules/fieldgroup/fieldgroup.module:129 +msgid "Style" +msgstr "Style" + +#: modules/fieldgroup/fieldgroup.module:132 +msgid "always open" +msgstr "toujours déplié" + +#: modules/fieldgroup/fieldgroup.module:133 +msgid "collapsible" +msgstr "repliable" + +#: modules/fieldgroup/fieldgroup.module:134 +msgid "collapsed" +msgstr "replié" + +#: modules/fieldgroup/fieldgroup.module:142 +msgid "Instructions to present to the user on the editing form." +msgstr "Instructions à présenter à l'utilisateur dans le formulaire d'édition." + +#: modules/fieldgroup/fieldgroup.module:147 +msgid "Display settings" +msgstr "Paramètres d'affichage" + +#: modules/fieldgroup/fieldgroup.module:148 +msgid "These settings apply to the group on node display." +msgstr "Ces paramètres s'appliquent au groupe à l'affichage du nœud." + +#: modules/fieldgroup/fieldgroup.module:155 +msgid "A description of the group." +msgstr "Description du groupe." + +#: modules/fieldgroup/fieldgroup.module:200 +msgid "Are you sure you want to remove the group %label?" +msgstr "Êtes-vous sûr(e) de vouloir supprimer le groupe '%label' ?" + +#: modules/fieldgroup/fieldgroup.module:202 +msgid "This action cannot be undone." +msgstr "Cette action est irréversible." + +#: modules/fieldgroup/fieldgroup.module:211 +msgid "The group %group_name has been removed." +msgstr "Le groupe '%group_name' a été supprimé." + +#: modules/fieldgroup/fieldgroup.module:260 +msgid "none" +msgstr "aucun" + +#: modules/fieldgroup/fieldgroup.module:353 +msgid "You need to provide a label." +msgstr "Vous devez fournir une étiquette." + +#: modules/fieldgroup/fieldgroup.module:358 +msgid "You need to provide a group name." +msgstr "Vous devez fournir un nom de groupe" + +#: modules/fieldgroup/fieldgroup.module:372 +msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Le nom de groupe %group_name n'est pas valide. Le nom ne doit contenir que des lettres sans accents, des nombres, et des underscores." + +#: modules/fieldgroup/fieldgroup.module:375 +msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix." +msgstr "Le nom de groupe %group_name est trop long. Le nom est limité à 32 caractères, le préfixe 'group_' compris." + +#: modules/fieldgroup/fieldgroup.module:381 +msgid "The group name %group_name already exists." +msgstr "Le nom de groupe %group_name existe déjà." + +#: modules/fieldgroup/fieldgroup.module:400;403 +msgid "Add new group:" +msgstr "Ajouter un nouveau groupe :" + +#: modules/fieldgroup/fieldgroup.module:418 +msgid "Add new group: you need to provide a label." +msgstr "Ajouter un nouveau groupe : vous devez fournir une étiquette." + +#: modules/fieldgroup/fieldgroup.module:419 +msgid "Add new group: you need to provide a group name." +msgstr "Ajouter un nouveau groupe : vous devez fournir un nom de groupe." + +#: modules/fieldgroup/fieldgroup.module:648 +msgid "Standard group" +msgstr "Groupe standard" + +#: modules/fieldgroup/fieldgroup.module:39;46 +msgid "Edit group" +msgstr "Éditer le groupe" + +#: modules/fieldgroup/fieldgroup.module:0 +msgid "fieldgroup" +msgstr "fieldgroup" + +#: modules/fieldgroup/fieldgroup.info:0 +msgid "Create display groups for CCK fields." +msgstr "Créée des groupes d'affichage pour les champs CCK." + +#: modules/nodereference/nodereference.rules.inc:15 +msgid "Load a referenced node" +msgstr "Charge un noeud référencé" + +#: modules/nodereference/nodereference.rules.inc:19 +msgid "Content containing the node reference field" +msgstr "Contenu contenant le champ node reference" + +#: modules/nodereference/nodereference.rules.inc:25 +msgid "Referenced content" +msgstr "Contenu référencé" + +#: modules/nodereference/nodereference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first content node will be loaded." +msgstr "Notez que si le champs possède des valeurs multiples, seul le premier contenu sera chargé." + +#: modules/nodereference/nodereference.rules.inc:50 +msgid "There are no nodereference fields defined." +msgstr "Il n'y a aucun champ nodereference défini." + +#: modules/nodereference/nodereference.module:60 +msgid "Node reference" +msgstr "Node référence" + +#: modules/nodereference/nodereference.module:61 +msgid "Store the ID of a related node as an integer value." +msgstr "Stocker l'ID du noeud lié en tant que valeur entière." + +#: modules/nodereference/nodereference.module:75 +msgid "Content types that can be referenced" +msgstr "Types de contenu pouvant être référencés" + +#: modules/nodereference/nodereference.module:87 +#: modules/userreference/userreference.module:84 +msgid "Default Views" +msgstr "Vues par défaut" + +#: modules/nodereference/nodereference.module:90 +#: modules/userreference/userreference.module:87 +msgid "Existing Views" +msgstr "Vues éxistantes" + +#: modules/nodereference/nodereference.module:97 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Avancé - Nœuds pouvant être référencés (Vue)" + +#: modules/nodereference/nodereference.module:104 +msgid "View used to select the nodes" +msgstr "Vue utilisée pour sélectionner les noeuds" + +#: modules/nodereference/nodereference.module:107 +msgid "<p>Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note:</p>" +msgstr "<p>Choisissez la vue du \"module Views\" qui sélectionne les noeuds pouvant être référencés.<br />Note :</p>" + +#: modules/nodereference/nodereference.module:108;121 +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "<ul><li>Seules les vues qui possèdent des champs fonctionneront à cet effet.</li><li>Ceci annulera les paramètres \"Types de contenu\" ci-dessus. Utilisez la section \"filtres\" de la vue à la place.</li><li>Utilisez la section \"champs\" de la vue pour afficher des informations supplémentaires à propos des noeuds candidats sur le formulaire de création/édition.</li><li>Utilisez la section \"critère de tri\" de la vue pour déterminer l'ordre dans lequel les noeuds candidats seront affichés.</li></ul>" + +#: modules/nodereference/nodereference.module:112 +#: modules/userreference/userreference.module:109 +msgid "View arguments" +msgstr "Arguments de la vue" + +#: modules/nodereference/nodereference.module:115 +#: modules/userreference/userreference.module:112 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Fournit une liste d'arguments, séparés par des virgules, à transmettre à la vue." + +#: modules/nodereference/nodereference.module:120 +msgid "<p>The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "<p>La liste des noeuds pouvant être référencés peut s'appuyer sur une vue du \"module Views\" mais aucune vue appropriée n'a été trouvée. <br />Note :</p>" + +#: modules/nodereference/nodereference.module:205 +#: modules/userreference/userreference.module:184 +msgid "%name: invalid input." +msgstr "%name : saisie non valide." + +#: modules/nodereference/nodereference.module:217 +msgid "%name: this post can't be referenced." +msgstr "%name : ce contenu ne peut être référencé." + +#: modules/nodereference/nodereference.module:242 +msgid "Title (link)" +msgstr "Titre (avec lien)" + +#: modules/nodereference/nodereference.module:247 +msgid "Title (no link)" +msgstr "Titre (sans lien)" + +#: modules/nodereference/nodereference.module:347 +#: modules/optionwidgets/optionwidgets.module:80 +#: modules/userreference/userreference.module:273 +msgid "Select list" +msgstr "Liste de sélection" + +#: modules/nodereference/nodereference.module:355 +#: modules/optionwidgets/optionwidgets.module:88 +#: modules/userreference/userreference.module:281 +msgid "Check boxes/radio buttons" +msgstr "Cases à cocher/boutons radio" + +#: modules/nodereference/nodereference.module:363 +#: modules/userreference/userreference.module:289 +msgid "Autocomplete text field" +msgstr "Champ texte à auto-complètement" + +#: modules/nodereference/nodereference.module:417 +#: modules/userreference/userreference.module:343 +msgid "Autocomplete matching" +msgstr "Correspondance de l'autocomplétion" + +#: modules/nodereference/nodereference.module:420 +#: modules/userreference/userreference.module:346 +msgid "Starts with" +msgstr "Commence par" + +#: modules/nodereference/nodereference.module:421 +#: modules/userreference/userreference.module:347 +msgid "Contains" +msgstr "Contient" + +#: modules/nodereference/nodereference.module:423 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes." +msgstr "Séléctionnez la méthode utilisée pour collecter les suggestions de l'autocomplétion. Notez que <em>Contient</em> peut engendrer des problèmes de performances sur des sites avec des milliers de noeuds" + +#: modules/nodereference/nodereference.module:671 +msgid "%name: title mismatch. Please check your selection." +msgstr "%name : différence de titre. Veuillez vérifier votre sélection." + +#: modules/nodereference/nodereference.module:678 +msgid "%name: found no valid post with that title." +msgstr "%name : aucun contenu valide n'a été trouvé pour ce titre." + +#: modules/nodereference/nodereference.module:15 +msgid "Nodereference autocomplete" +msgstr "Autocomplétion de nodereference" + +#: modules/nodereference/nodereference.module:0 +msgid "nodereference" +msgstr "nodereference" + +#: modules/nodereference/nodereference.info:0 +msgid "Node Reference" +msgstr "Node Reference" + +#: modules/nodereference/nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "Définit un type de champ pour référencer un noeud depuis un autre noeud." + +#: modules/number/number.module:34 +msgid "Integer" +msgstr "Entier" + +#: modules/number/number.module:35 +msgid "Store a number in the database as an integer." +msgstr "Stocke un nombre dans la base de données en format entier." + +#: modules/number/number.module:38 +msgid "Decimal" +msgstr "Décimal" + +#: modules/number/number.module:39 +msgid "Store a number in the database in a fixed decimal format." +msgstr "Stocke un nombre dans la base de données en format décimal fixe." + +#: modules/number/number.module:42 +msgid "Float" +msgstr "Réel (Float)" + +#: modules/number/number.module:43 +msgid "Store a number in the database in a floating point format." +msgstr "Stocke un nombre dans la base de données en format réel." + +#: modules/number/number.module:57 +msgid "Minimum" +msgstr "Minimum" + +#: modules/number/number.module:63 +msgid "Maximum" +msgstr "Maximum" + +#: modules/number/number.module:71 +msgid "Precision" +msgstr "Précision" + +#: modules/number/number.module:72 +msgid "The total number of digits to store in the database, including those to the right of the decimal." +msgstr "Le nombre total de chiffres à stocker dans la base de données, en incluant ceux à droite de la virgule." + +#: modules/number/number.module:78 +msgid "Scale" +msgstr "Echelle" + +#: modules/number/number.module:79 +msgid "The number of digits to the right of the decimal." +msgstr "Le nombre de chiffres à droite de la virgule" + +#: modules/number/number.module:85 +msgid "Decimal marker" +msgstr "Séparateur de décimales" + +#: modules/number/number.module:86 +msgid "The character users will input to mark the decimal point in forms." +msgstr "Le caractère que les utilisateurs saisiront pour séparer les décimales dans les formulaires." + +#: modules/number/number.module:92 +msgid "Prefix" +msgstr "Préfixe" + +#: modules/number/number.module:95 +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Définissez une chaîne de caractères à utiliser pour préfixer la valeur, par exemple $ ou €. Laissez vide pour ne rien afficher de plus. Séparez les valeurs singulier et pluriel par une barre verticale (euro|euros)." + +#: modules/number/number.module:99 +msgid "Suffix" +msgstr "Suffixe" + +#: modules/number/number.module:102 +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Définissez une chaîne qui sera ajoutée en suffixe à la valeur, comme m², m/s², kb/s. Laisser vide pour aucun suffixe. Séparez les singulier et pluriel avec un pipe (mètre|mètres)." + +#: modules/number/number.module:106 +#: modules/text/text.module:71 +msgid "Allowed values" +msgstr "Valeurs autorisées" + +#: modules/number/number.module:112 +#: modules/text/text.module:77 +msgid "Allowed values list" +msgstr "Liste des valeurs autorisées" + +#: modules/number/number.module:116 +#: modules/text/text.module:81 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "Les valeurs possibles que ce champ peut contenir. Entrez une valeur par ligne, sous la forme clé|étiquette. La clé est une valeur qui sera stocker dans la base de données, elle doit correspondre au type de champ défini (%type). L'étiquette est optionnelle, si elle n'est pas précisée, la clé sera utilisée également comme étiquette.<br />Balises HTML autorisées : @tags" + +#: modules/number/number.module:130 +#: modules/text/text.module:95 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Pour usage avancé seulement : code PHP fournissant un tableau par clé des valeurs autorisées. Ne doit pas inclure les délimiteurs <?php ?>. Si ce champ est rempli, le tableau renvoyé par le code prendra le pas sur la liste des valeurs autorisées apparaissant ci-dessus." + +#: modules/number/number.module:138 +#: modules/text/text.module:103 +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "Ce code PHP a été saisi par un administrateur et supplantera la liste des valeurs permises ci-dessus." + +#: modules/number/number.module:178 +#: modules/text/text.module:132 +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Valeurs autorisées" + +#: modules/number/number.module:195 +msgid "\"Minimum\" must be a number." +msgstr "\"Minimum\" doit être un nombre." + +#: modules/number/number.module:202 +msgid "\"Maximum\" must be a number." +msgstr "\"Maximum\" doit être un nombre." + +#: modules/number/number.module:219 +msgid "%name: the value may be no smaller than %min." +msgstr "%name : la valeur ne peut être inférieure à %min." + +#: modules/number/number.module:222 +msgid "%name: the value may be no larger than %max." +msgstr "%name : la valeur ne peut être supérieure à %max." + +#: modules/number/number.module:235 +#: modules/text/text.module:156 +msgid "%name: illegal value." +msgstr "%name : valeur illégale." + +#: modules/number/number.module:270 +msgid "unformatted" +msgstr "non mis en forme" + +#: modules/number/number.module:353 +#: modules/text/text.module:256 +msgid "Text field" +msgstr "Champ texte" + +#: modules/number/number.module:512 +msgid "Only numbers and decimals are allowed in %field." +msgstr "Seuls les nombres et les décimaux sont autorisés dans %field." + +#: modules/number/number.module:535 +msgid "Only numbers are allowed in %field." +msgstr "Seuls les nombres sont autorisés dans %field." + +#: modules/number/number.module:559 +msgid "Only numbers and the decimal character (%decimal) are allowed in %field." +msgstr "Seuls les nombres et le caractère décimal (%decimal) sont autorisés dans %field." + +#: modules/number/number.module:0 +msgid "number" +msgstr "nombre" + +#: modules/number/number.info:0 +msgid "Number" +msgstr "Nombre" + +#: modules/number/number.info:0 +msgid "Defines numeric field types." +msgstr "Définit des types de champs numériques." + +#: modules/optionwidgets/optionwidgets.module:19 +msgid "Create a list of options as a list in <strong>Allowed values list</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "Créez une liste d'options en tant que liste dans la <strong>Liste des valeurs autorisées</strong>, ou en tant que tableau en code PHP. Ces valeurs seront les mêmes pour le champ %field au sein de tous les types de contenu." + +#: modules/optionwidgets/optionwidgets.module:22 +msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "Pour un widget 'case à cocher oui/non', définissez la valeur 'non' en premier, puis la valeur 'oui', dans la section <strong>Valeurs autorisées</strong>. Notez que la case à cocher sera étiquetée avec l'étiquette de la valeur du 'oui'." + +#: modules/optionwidgets/optionwidgets.module:25 +msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "Le widget 'cases à cocher/boutons radio' affichera des cases à cocher si l'option valeurs multiples est sélectionnées pour ce champ, autrement, des boutons radio seront affichés." + +#: modules/optionwidgets/optionwidgets.module:37 +msgid "You need to specify the 'allowed values' for this field." +msgstr "Vous devez préciser les 'valeurs autorisées' pour ce champ." + +#: modules/optionwidgets/optionwidgets.module:96 +msgid "Single on/off checkbox" +msgstr "Case à cocher on/off unique" + +#: modules/optionwidgets/optionwidgets.module:331 +msgid "%name: this field cannot hold more that @count values." +msgstr "%name : ce champ ne peut contenir plus de @count valeurs." + +#: modules/optionwidgets/optionwidgets.module:416 +msgid "N/A" +msgstr "N/A" + +#: modules/optionwidgets/optionwidgets.module:420 +msgid "- None -" +msgstr "- Aucun -" + +#: modules/optionwidgets/optionwidgets.module:0 +msgid "optionwidgets" +msgstr "optionwidgets" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Option Widgets" + +#: modules/optionwidgets/optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "Définit des widgets de liste déroulante, case à cocher et bouton radio pour des champs texte et numériques." + +#: modules/text/text.module:41 +#: modules/text/text.info:0 +msgid "Text" +msgstr "Texte" + +#: modules/text/text.module:42 +msgid "Store text in the database." +msgstr "Enregistre le texte dans la base de données." + +#: modules/text/text.module:54;201 +#: modules/userreference/userreference.module:226 +msgid "Plain text" +msgstr "Texte simple" + +#: modules/text/text.module:54 +msgid "Filtered text (user selects input format)" +msgstr "Texte filtré (l'utilisateur choisit le format d'entrée)" + +#: modules/text/text.module:57 +msgid "Text processing" +msgstr "Traitement du texte" + +#: modules/text/text.module:63 +msgid "Maximum length" +msgstr "Taille maximale" + +#: modules/text/text.module:67 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "La taille maximale des champs, en caractères. Laisser vide pour ne pas limiter la taille." + +#: modules/text/text.module:159 +msgid "%name: the value may not be longer than %max characters." +msgstr "%name : la valeur ne doit pas dépasser %max caractères." + +#: modules/text/text.module:196 +#: modules/userreference/userreference.module:221 +msgid "Default" +msgstr "Par défaut" + +#: modules/text/text.module:206 +msgid "Trimmed" +msgstr "Coupé" + +#: modules/text/text.module:264 +msgid "Text area (multiple rows)" +msgstr "Zone de texte (plusieurs lignes)" + +#: modules/text/text.module:316 +msgid "Size of textfield" +msgstr "Taille du champ texte" + +#: modules/text/text.module:325 +msgid "Rows" +msgstr "Rangées" + +#: modules/text/text.module:0 +msgid "text" +msgstr "texte" + +#: modules/text/text.info:0 +msgid "Defines simple text field types." +msgstr "Définit les types de champs en texte simple." + +#: modules/userreference/userreference.rules.inc:15 +msgid "Load a referenced user" +msgstr "Charge un utilisateur référencé" + +#: modules/userreference/userreference.rules.inc:19 +msgid "Content containing the user reference field" +msgstr "Contenu contenant le champ userrefernece" + +#: modules/userreference/userreference.rules.inc:25 +msgid "Referenced user" +msgstr "Utilisateur référencé" + +#: modules/userreference/userreference.rules.inc:29 +msgid "Note that if the field has multiple values, only the first user will be loaded." +msgstr "Noter que si le champ possède des valeurs multiples, seul le premier utilisateur sera chargé" + +#: modules/userreference/userreference.rules.inc:52 +msgid "There are no userreference fields defined." +msgstr "Il n'y a aucun champ userreference défini" + +#: modules/userreference/userreference.module:52 +msgid "User reference" +msgstr "User reference" + +#: modules/userreference/userreference.module:53 +msgid "Store the ID of a related user as an integer value." +msgstr "Stocke l'ID d'un utilisateur lié sous forme d'entier" + +#: modules/userreference/userreference.module:67 +msgid "User roles that can be referenced" +msgstr "Rôles utilisateur pouvant être référencés" + +#: modules/userreference/userreference.module:73 +msgid "User status that can be referenced" +msgstr "Statuts utilisateur pouvant être référencés" + +#: modules/userreference/userreference.module:75 +msgid "Active" +msgstr "Actif" + +#: modules/userreference/userreference.module:75 +msgid "Blocked" +msgstr "Bloqué" + +#: modules/userreference/userreference.module:94 +msgid "Advanced - Users that can be referenced (View)" +msgstr "Avancé - Utilisateurs pouvant être référencés (Vue)" + +#: modules/userreference/userreference.module:101 +msgid "View used to select the users" +msgstr "Vue utilisée pour sélectionner les utilisateurs" + +#: modules/userreference/userreference.module:104 +msgid "<p>Choose the \"Views module\" view that selects the users that can be referenced.<br />Note:</p>" +msgstr "<p>Choisissez la vue du \"module Views\" qui sélectionne les utilisateurs pouvant être référencés.<br />Note :</p>" + +#: modules/userreference/userreference.module:105;118 +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.</li></ul>" +msgstr "<ul><li>Seules les vues qui possèdent des champs fonctionneront à cet effet.</li><li>Ceci annulera les paramètres \"Rôles Référençables\" et \"Statut Référençable\" ci-dessus. Utilisez la section \"filtres\" de la vue à la place.</li><li>Utilisez la section \"champs\" de la vue pour afficher des informations supplémentaires à propos des utilisateurs candidats sur le formulaire de création/édition.</li><li>Utilisez la section \"critère de tri\" de la vue pour déterminer l'ordre dans lequel les utilisateurs candidats seront affichés.</li></ul>" + +#: modules/userreference/userreference.module:117 +msgid "<p>The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "<p>La liste d'utilisateurs pouvant être référencés peut s'appueyr sur une vue du \"module Views\", mais aucune vue appropriée n'a été trouvée. <br />Note :</p>" + +#: modules/userreference/userreference.module:196 +msgid "%name: invalid user." +msgstr "%name : utilisateur invalide." + +#: modules/userreference/userreference.module:349 +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users." +msgstr "Séléctionnez la méthode utilisée pour collecter les suggestions de l'autocomplétion. Notez que <em>Contient</em> peut engendrer des problèmes de performances sur des sites avec des milliers d'utilisateurs." + +#: modules/userreference/userreference.module:357 +msgid "Reverse link" +msgstr "Lien retour" + +#: modules/userreference/userreference.module:359 +msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record." +msgstr "Si cette option est sélectionnée, un lien réciproque vers le nœud référençant sera affiché dans l'enregistrement utilisateur référencé." + +#: modules/userreference/userreference.module:594 +msgid "%name: found no valid user with that name." +msgstr "%name : nous n'avons pas trouvé d'utilisateur valide pour ce nom." + +#: modules/userreference/userreference.module:887 +msgid "Related content" +msgstr "Contenu lié" + +#: modules/userreference/userreference.module:15 +msgid "Userreference autocomplete" +msgstr "Autocomplétion Userreference" + +#: modules/userreference/userreference.module:0 +msgid "userreference" +msgstr "userreference" + +#: modules/userreference/userreference.info:0 +msgid "User Reference" +msgstr "User Reference" + +#: modules/userreference/userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "Définit un type de champ pour référencer un utilisateur depuis un noeud." + +#: theme/content-admin-field-overview-form.tpl.php:11 +msgid "Weight" +msgstr "Poids" + +#: theme/content-admin-field-overview-form.tpl.php:53 +msgid "Add" +msgstr "Ajouter" + +#: theme/content-admin-field-overview-form.tpl.php:59 +msgid "New field" +msgstr "Nouveau champ" + +#: theme/content-admin-field-overview-form.tpl.php:72 +msgid "Existing field" +msgstr "Champ existant" + +#: theme/content-admin-field-overview-form.tpl.php:84 +msgid "New group" +msgstr "Nouveau groupe" + +#: theme/theme.inc:11 +msgid "Add fields and groups to the content type, and arrange them on content display and input forms." +msgstr "Ajouter des champs et des groupes au type de contenu, et les paramétrer pour l'affichage du contenu et les formulaires de saisie." + +#: theme/theme.inc:13 +msgid "You can add a field to a group by dragging it below and to the right of the group." +msgstr "Vous pouvez ajouter un champ à un groupe en le faisant glisser ci-dessous et à la droite du groupe." + +#: theme/theme.inc:16 +msgid "Note: Installing the <a href=\"!adv_help\">Advanced help</a> module will let you access more and better help." +msgstr "Note : l'installation du module <a href=\"!adv_help\">Aide avancée (Advanced help)</a> vous permettra d'accéder à plus d'aide, et de meilleure qualité." + +#: theme/theme.inc:111 +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "Configurez ici la manière dont les champs et étiquettes de champs de ce type de contenu doivent être affichées, lorsque le contenu est vu en mode accroche ou en pleine page." + +#: theme/theme.inc:114 +msgid "Configure how this content type's fields should be displayed when it's rendered in the following contexts." +msgstr "Configurez ici la façon dont les champs de ce type de contenu doivent être affichés lorsqu'il est rendu dans les contextes suivants." + +#: theme/theme.inc:116 +msgid "Use the 'Exclude' checkbox to exclude an item from the !content value passed to the node template." +msgstr "Utiliser la case à cocher 'Exclure' pour exclure un élément de la valeur de !content transmis au gabarit du node." + +#: theme/content-edit.js:0 +msgid "Remove this item" +msgstr "Supprimer cet élément" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/general.de.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/general.de.po new file mode 100644 index 0000000000000000000000000000000000000000..d1618b7693af9c5ac93c961b74e3c035cbaaeaf5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/general.de.po @@ -0,0 +1,308 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content.module,v 1.301.2.3 2008/06/14 02:24:00 yched +# nodereference.module,v 1.138.2.1 2008/06/04 12:56:58 karens +# content.crud.inc,v 1.76.2.1 2008/06/04 11:53:57 karens +# content_copy.module,v 1.27 2008/05/29 22:27:04 karens +# content.admin.inc,v 1.181.2.2 2008/06/14 02:50:08 yched +# example_field.php,v 1.5 2008/04/23 08:24:06 karens +# simple_field.php,v 1.5 2008/04/23 08:24:06 karens +# text.module,v 1.95.2.2 2008/06/14 02:50:08 yched +# userreference.module,v 1.106 2008/06/01 22:00:36 karens +# number.module,v 1.91.2.3 2008/06/14 02:50:08 yched +# fieldgroup.module,v 1.79.2.1 2008/06/13 21:41:06 yched +# optionwidgets.module,v 1.69 2008/06/03 12:25:45 karens +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:15+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" + +#: content.module:499 +#: modules/content_multigroup/content_multigroup.module:903 +msgid "Order" +msgstr "Reihenfolge" + +#: content.module:1857 +#: modules/nodereference/nodereference.module:268 +msgid "Teaser" +msgstr "Anrisstext" + +#: content.module:1861 +#: modules/nodereference/nodereference.module:263 +msgid "Full node" +msgstr "Vollständiger Beitrag" + +#: content.module:595;602;0 +#: includes/content.crud.inc:589;633 +msgid "content" +msgstr "Inhalt" + +#: includes/content.admin.inc:16 +#: modules/content_copy/content_copy_export_form.tpl.php:11 +#: theme/content-admin-field-overview-form.tpl.php:12 +msgid "Name" +msgstr "Name" + +#: includes/content.admin.inc:16 +#: modules/content_copy/content_copy_export_form.tpl.php:12 +#: theme/content-admin-field-overview-form.tpl.php:13 +msgid "Type" +msgstr "Typ" + +#: includes/content.admin.inc:16 +#: modules/fieldgroup/fieldgroup.module:158 +msgid "Description" +msgstr "Beschreibung" + +#: includes/content.admin.inc:16 +#: theme/content-admin-field-overview-form.tpl.php:14 +msgid "Operations" +msgstr "Operationen" + +#: includes/content.admin.inc:171;197;895 +#: modules/fieldgroup/fieldgroup.module:209 +msgid "Remove" +msgstr "Entfernen" + +#: includes/content.admin.inc:244;285;315;804;985 +#: includes/panels/content_types/content_field.inc:97 +#: includes/views/handlers/content_handler_field.inc:56 +#: modules/content_copy/content_copy_export_form.tpl.php:10 +#: modules/fieldgroup/fieldgroup.module:117 +#: theme/content-admin-display-overview-form.tpl.php:13 +#: theme/content-admin-field-overview-form.tpl.php:10 +msgid "Label" +msgstr "Bezeichnung" + +#: includes/content.admin.inc:344 +#: modules/content_multigroup/content_multigroup.module:126 +msgid "Type of group." +msgstr "Typ der Gruppe." + +#: includes/content.admin.inc:352;677 +#: modules/fieldgroup/fieldgroup.module:177;341 +msgid "Save" +msgstr "Speichern" + +#: includes/content.admin.inc:585;633 +#: includes/panels/content_types/content_field.inc:101 +#: modules/content_multigroup/content_multigroup.module:352 +msgid "Above" +msgstr "Oberhalb" + +#: includes/content.admin.inc:586 +#: includes/panels/content_types/content_field.inc:102 +msgid "Inline" +msgstr "Inline" + +#: includes/content.admin.inc:587;614;634;642 +#: modules/content_multigroup/content_multigroup.module:353;360 +msgid "<Hidden>" +msgstr "<Versteckt>" + +#: includes/content.admin.inc:625;668 +#: theme/content-admin-display-overview-form.tpl.php:17 +msgid "Exclude" +msgstr "Ausschließen" + +#: includes/content.admin.inc:895 +#: modules/fieldgroup/fieldgroup.module:209 +msgid "Cancel" +msgstr "Abbrechen" + +#: includes/content.admin.inc:1031 +#: modules/fieldgroup/fieldgroup.module:145 +msgid "Help text" +msgstr "Hilfetext" + +#: includes/content.admin.inc:1081 +#: modules/number/number.module:123 +#: modules/text/text.module:86 +msgid "PHP code" +msgstr "PHP-Code" + +#: includes/content.admin.inc:1096;1109 +#: includes/content.rules.inc:99 +#: modules/number/number.module:130;139 +#: modules/text/text.module:93;102 +msgid "Code" +msgstr "Kürzel" + +#: includes/content.admin.inc:1110 +#: modules/number/number.module:140 +#: modules/text/text.module:103 +msgid "<none>" +msgstr "<Keine>" + +#: includes/content.admin.inc:1111 +#: modules/number/number.module:141 +#: modules/text/text.module:104 +msgid "You're not allowed to input PHP code." +msgstr "Keine Berechtigung zur Eingabe von PHP-Code vorhanden." + +#: includes/content.admin.inc:1134 +#: modules/content_multigroup/content_multigroup.module:73 +msgid "Unlimited" +msgstr "Unbegrenzt" + +#: includes/content.admin.inc:1151 +#: modules/content_copy/content_copy.module:251 +msgid "Save field settings" +msgstr "Feldeinstellungen speichern" + +#: includes/content.rules.inc:53;276 +#: modules/nodereference/nodereference.rules.inc:45 +#: modules/userreference/userreference.rules.inc:47 +#: theme/content-admin-display-overview-form.tpl.php:11 +msgid "Field" +msgstr "Feld" + +#: includes/panels/content_types/content_field.inc:45 +#: modules/fieldgroup/fieldgroup.panels.inc:31 +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:43 +#: modules/nodereference/panels/relationships/node_from_noderef.inc:17 +#: modules/userreference/panels/relationships/user_from_userref.inc:17 +msgid "Node" +msgstr "Beitrag" + +#: modules/content_multigroup/content_multigroup.module:356 +#: modules/fieldgroup/fieldgroup.module:266 +msgid "none" +msgstr "Keine" + +#: modules/fieldgroup/fieldgroup.panels.inc:10;27 +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:14 +msgid "Content fieldgroup" +msgstr "Inhaltsfeldgruppe" + +#: modules/fieldgroup/fieldgroup.panels.inc:112 +#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:102 +msgid "Text to display if group has no data. Note that title will not display unless overridden." +msgstr "Der bei einer Gruppe ohne Daten anzuzeigende Text. Der Titel wird nur angezeigt, wenn dieser Übersteuert wird." + +#: modules/nodereference/nodereference.module:97 +#: modules/userreference/userreference.module:94 +msgid "Default Views" +msgstr "Standardansichten" + +#: modules/nodereference/nodereference.module:100 +#: modules/userreference/userreference.module:97 +msgid "Existing Views" +msgstr "Vorhandene Ansichten" + +#: modules/nodereference/nodereference.module:122 +#: modules/userreference/userreference.module:119 +msgid "View arguments" +msgstr "Argumente anzeigen" + +#: modules/nodereference/nodereference.module:125 +#: modules/userreference/userreference.module:122 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Eine kommagetrennte Liste von Argumenten angeben, welche an die Ansicht übergeben werden." + +#: modules/nodereference/nodereference.module:216 +#: modules/userreference/userreference.module:195 +msgid "%name: invalid input." +msgstr "%name: ungültige Eingabe." + +#: modules/nodereference/nodereference.module:358 +#: modules/optionwidgets/optionwidgets.module:80 +#: modules/userreference/userreference.module:284 +msgid "Select list" +msgstr "Auswahlliste" + +#: modules/nodereference/nodereference.module:366 +#: modules/optionwidgets/optionwidgets.module:88 +#: modules/userreference/userreference.module:292 +msgid "Check boxes/radio buttons" +msgstr "Ankreuzfelder/Auswahlknöpfe" + +#: modules/nodereference/nodereference.module:374 +#: modules/userreference/userreference.module:300 +msgid "Autocomplete text field" +msgstr "Textfeld mit Autovervollständigung" + +#: modules/nodereference/nodereference.module:429 +#: modules/userreference/userreference.module:355 +msgid "Autocomplete matching" +msgstr "Autovervollständigungsvergleich" + +#: modules/nodereference/nodereference.module:432 +#: modules/userreference/userreference.module:358 +msgid "Starts with" +msgstr "Beginnt mit" + +#: modules/nodereference/nodereference.module:433 +#: modules/userreference/userreference.module:359 +msgid "Contains" +msgstr "Enthält" + +#: modules/nodereference/nodereference.module:439 +#: modules/text/text.module:317 +#: modules/userreference/userreference.module:365 +msgid "Size of textfield" +msgstr "Größe des Textfeldes" + +#: modules/number/number.module:109 +#: modules/text/text.module:72 +msgid "Allowed values" +msgstr "Zulässige Werte" + +#: modules/number/number.module:115 +#: modules/text/text.module:78 +msgid "Allowed values list" +msgstr "Zulässige Werteliste" + +#: modules/number/number.module:119 +#: modules/text/text.module:82 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "Die möglichen Werte, die dieses Feld enthalten kann. Geben Sie pro Zeile einen Wert im Format „Schlüssel|Bezeichnung“ ein. Der Schüssel ist der Wert, welcher in der Datenbank gespeichert wird und muss dem Datentyp (%type) des Feldes entsprechen. Der Schlüssel wird als Bezeichnung verwendet, wenn die optionale Bezeichnung nicht angegeben wird.<br />Zulässige HTML-Tags: @tags" + +#: modules/number/number.module:133 +#: modules/text/text.module:96 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Nur erweiterte Verwendung: PHP-Code der ein Array mit Schlüsseln der zulässigen Werte zurückliefert. Dieser sollte keine <?php ?> Trennzeichen enthalten. Sollte dieses Feld ausgefüllt werden, wird das von diesem Code zurückgegebene Array die zulässige Werteliste oberhalb übersteuern." + +#: modules/number/number.module:141 +#: modules/text/text.module:104 +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "Dieser PHP-Code wurde von einem Administrator festgelegt und wird die obige zulässige Werteliste übersteuern." + +#: modules/number/number.module:181 +#: modules/text/text.module:133 +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Zulässige Werte" + +#: modules/number/number.module:238 +#: modules/text/text.module:157 +msgid "%name: illegal value." +msgstr "%name: ungültiger Wert." + +#: modules/number/number.module:356 +#: modules/text/text.module:257 +msgid "Text field" +msgstr "Textfeld" + +#: modules/text/text.module:55;202 +#: modules/userreference/userreference.module:237 +msgid "Plain text" +msgstr "Einfacher Text" + +#: modules/text/text.module:197 +#: modules/userreference/userreference.module:232 +msgid "Default" +msgstr "Standard" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/general.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/general.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..047c85fdd27006d9358ec806d242ef0ca6b56e59 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/general.fr.po @@ -0,0 +1,207 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 13:24+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: content.module:1635 modules/nodereference/nodereference.module:215 +msgid "Teaser" +msgstr "Résumé" + +#: content.module:1636 modules/nodereference/nodereference.module:210 +msgid "Full node" +msgstr "Nœud complet" + +#: content.module:557;564;0 includes/content.crud.inc:591;629 +msgid "content" +msgstr "contenu" + +#: content.module:103 modules/content_copy/content_copy.module:125 +msgid "Fields" +msgstr "Champs" + +#: content.module:156 includes/content.admin.inc:528 +msgid "Add field" +msgstr "Ajouter un champ" + +#: examples/example_field.php:158;388 examples/simple_field.php:332 +#: modules/text/text.module:66;209 +#: modules/userreference/userreference.module:151 +msgid "Plain text" +msgstr "Texte simple" + +#: examples/example_field.php:158 modules/text/text.module:66 +msgid "Filtered text (user selects input format)" +msgstr "Texte filtré (l'utilisateur choisit le format d'entrée)" + +#: examples/example_field.php:161 modules/text/text.module:69 +msgid "Text processing" +msgstr "Traitement du texte" + +#: examples/example_field.php:167 examples/simple_field.php:164 +#: modules/text/text.module:75 +msgid "Maximum length" +msgstr "Taille maximale" + +#: examples/example_field.php:170 examples/simple_field.php:167 +#: modules/text/text.module:78 +msgid "" +"The maximum length of the field in characters. Leave blank for an unlimited " +"size." +msgstr "" +"La taille maximale des champs, en caractères. Laisser vide pour ne pas " +"limiter la taille." + +#: examples/example_field.php:174 modules/number/number.module:129 +#: modules/text/text.module:88 +msgid "Allowed values list" +msgstr "Liste des valeurs autorisées" + +#: examples/example_field.php:182 includes/content.admin.inc:930 +#: modules/number/number.module:137 modules/text/text.module:96 +msgid "PHP code" +msgstr "Code PHP" + +#: examples/example_field.php:188 includes/content.admin.inc:951;964 +#: modules/number/number.module:144;153 modules/text/text.module:103;112 +msgid "Code" +msgstr "Code" + +#: examples/example_field.php:191 modules/number/number.module:147 +#: modules/text/text.module:106 +msgid "" +"Advanced usage only: PHP code that returns a keyed array of allowed values. " +"Should not include <?php ?> delimiters. If this field is filled out, " +"the array returned by this code will override the allowed values list above." +msgstr "" +"Pour usage avancé seulement : code PHP fournissant un tableau par clé des " +"valeurs autorisées. Ne doit pas inclure les délimiteurs <?php ?>. Si " +"ce champ est rempli, le tableau renvoyé par le code prendra le pas sur la " +"liste des valeurs autorisées apparaissant ci-dessus." + +#: examples/example_field.php:278 modules/number/number.module:228 +#: modules/text/text.module:160 +msgid "Illegal value for %name." +msgstr "Valeur illégale pour le champ '%name'." + +#: examples/example_field.php:287 examples/simple_field.php:231 +#: modules/text/text.module:169 +msgid "%label is longer than %max characters." +msgstr "La longueur de '%label' dépasse %max caractères." + +#: examples/example_field.php:383 examples/simple_field.php:327 +#: modules/text/text.module:204 modules/userreference/userreference.module:146 +msgid "Default" +msgstr "Par défaut" + +#: examples/example_field.php:393 modules/text/text.module:214 +msgid "Trimmed" +msgstr "Coupé" + +#: examples/example_field.php:476 examples/simple_field.php:400 +#: modules/number/number.module:342 modules/text/text.module:264 +msgid "Text field" +msgstr "Champ texte" + +#: examples/example_field.php:551 examples/simple_field.php:430 +#: modules/text/text.module:324 +msgid "Rows" +msgstr "Rangées" + +#: examples/example_field.php:560 examples/simple_field.php:438 +#: modules/text/text.module:333 +msgid "\"Rows\" must be a positive integer." +msgstr "Le champ 'Rangées' doit être un entier positif." + +#: includes/content.admin.inc:16 modules/fieldgroup/fieldgroup.module:156 +msgid "Description" +msgstr "Description" + +#: includes/content.admin.inc:148;164;790 +#: modules/fieldgroup/fieldgroup.module:236 +msgid "Remove" +msgstr "Ôter" + +#: includes/content.admin.inc:201;402 +#: modules/fieldgroup/fieldgroup.module:110;363 +msgid "Save" +msgstr "Enregistrer" + +#: includes/content.admin.inc:212;413;623;850 +#: modules/fieldgroup/fieldgroup.module:121 +msgid "Label" +msgstr "Étiquette" + +#: includes/content.admin.inc:790 modules/fieldgroup/fieldgroup.module:236 +msgid "Cancel" +msgstr "Annuler" + +#: includes/content.admin.inc:897 modules/fieldgroup/fieldgroup.module:143 +msgid "Help text" +msgstr "Texte d'aide" + +#: includes/content.admin.inc:965 modules/number/number.module:154 +#: modules/text/text.module:113 +msgid "<none>" +msgstr "<aucun>" + +#: includes/content.admin.inc:966 modules/number/number.module:155 +#: modules/text/text.module:114 +msgid "You're not allowed to input PHP code." +msgstr "Vous n'êtes pas autorisé à saisir du code PHP." + +#: modules/fieldgroup/fieldgroup.module:293 +#: modules/nodereference/nodereference.module:544 +#: modules/userreference/userreference.module:439 +msgid "none" +msgstr "aucun" + +#: modules/nodereference/nodereference.module:303 +#: modules/optionwidgets/optionwidgets.module:62 +#: modules/userreference/userreference.module:198 +msgid "Select list" +msgstr "Liste de sélection" + +#: modules/nodereference/nodereference.module:311 +#: modules/userreference/userreference.module:206 +msgid "Autocomplete text field" +msgstr "Champ texte à auto-complètement" + +#: modules/number/number.module:123 modules/text/text.module:82 +msgid "Allowed values" +msgstr "Valeurs permises" + +#: modules/number/number.module:133 modules/text/text.module:92 +msgid "" +"The possible values this field can contain. Enter one value per line, in the " +"format key|label. The key is the value that will be stored in the database " +"and it must match the field storage type, %type. The label is optional and " +"the key will be used as the label if no label is specified.<br />Allowed " +"HTML tags: @tags" +msgstr "" +"Les valeurs que ce champ peut contenir. Saisissez une valeur par ligne, au " +"format clé|libellé. La clé est la valeur qui sera enregistrée dans la base " +"de données et elle doit correspondre au type définit pour le champ dans la " +"base, '%type'. Le libellé est optionnel et, si aucune valeur n'est " +"spécifiée, la clé sera utilisée comme libellé.<br />Balises HTML " +"autorisées : @tags" + +#: modules/number/number.module:155 modules/text/text.module:114 +msgid "" +"This PHP code was set by an administrator and will override the allowed " +"values list above." +msgstr "" +"Ce code PHP a été saisi par un administrateur et supplantera la liste des " +"valeurs permises ci-dessus." diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/general.pot b/drupal/sites/default/boinc/modules/contrib/cck/translations/general.pot new file mode 100644 index 0000000000000000000000000000000000000000..49518c933b590b8dcdf7077c02f874bb827a083d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/general.pot @@ -0,0 +1,246 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content.module,v 1.301.2.106 2009/06/02 12:24:04 yched +# content_multigroup.module,v 1.1.2.4 2008/10/22 11:02:41 yched +# nodereference.module,v 1.138.2.55 2009/06/02 12:24:04 yched +# content.crud.inc,v 1.76.2.14 2008/11/07 15:02:02 yched +# content.admin.inc,v 1.181.2.68 2009/06/02 14:49:07 yched +# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched +# content-admin-field-overview-form.tpl.php,v 1.1.2.5 2008/10/16 14:40:54 yched +# fieldgroup.module,v 1.79.2.48 2009/04/29 20:51:52 karens +# content_field.inc,v 1.1.2.4 2009/06/02 15:05:27 yched +# content_handler_field.inc,v 1.1.2.15 2009/03/30 22:54:16 yched +# content-admin-display-overview-form.tpl.php,v 1.1.2.3 2008/10/09 20:58:26 karens +# number.module,v 1.91.2.35 2009/04/29 20:51:53 karens +# text.module,v 1.95.2.29 2009/04/29 20:51:53 karens +# content.rules.inc,v 1.1.2.6 2009/04/30 09:56:07 fago +# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched +# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched +# content_fieldgroup.inc,v 1.1.2.1 2009/04/29 18:34:46 karens +# node_from_noderef.inc,v 1.1.2.1 2009/06/02 12:24:03 yched +# user_from_userref.inc,v 1.1.2.1 2009/06/02 12:24:04 yched +# userreference.module,v 1.106.2.43 2009/06/02 12:24:04 yched +# optionwidgets.module,v 1.69.2.23 2009/03/18 21:00:58 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: content.module:499 modules/content_multigroup/content_multigroup.module:903 +msgid "Order" +msgstr "" + +#: content.module:1857 modules/nodereference/nodereference.module:268 +msgid "Teaser" +msgstr "" + +#: content.module:1861 modules/nodereference/nodereference.module:263 +msgid "Full node" +msgstr "" + +#: content.module:595;602;0 includes/content.crud.inc:589;633 +msgid "content" +msgstr "" + +#: includes/content.admin.inc:16 modules/content_copy/content_copy_export_form.tpl.php:11 theme/content-admin-field-overview-form.tpl.php:12 +msgid "Name" +msgstr "" + +#: includes/content.admin.inc:16 modules/content_copy/content_copy_export_form.tpl.php:12 theme/content-admin-field-overview-form.tpl.php:13 +msgid "Type" +msgstr "" + +#: includes/content.admin.inc:16 modules/fieldgroup/fieldgroup.module:158 +msgid "Description" +msgstr "" + +#: includes/content.admin.inc:16 theme/content-admin-field-overview-form.tpl.php:14 +msgid "Operations" +msgstr "" + +#: includes/content.admin.inc:171;197;895 modules/fieldgroup/fieldgroup.module:209 +msgid "Remove" +msgstr "" + +#: includes/content.admin.inc:244;285;315;804;985 includes/panels/content_types/content_field.inc:97 includes/views/handlers/content_handler_field.inc:56 modules/content_copy/content_copy_export_form.tpl.php:10 modules/fieldgroup/fieldgroup.module:117 theme/content-admin-display-overview-form.tpl.php:13 theme/content-admin-field-overview-form.tpl.php:10 +msgid "Label" +msgstr "" + +#: includes/content.admin.inc:344 modules/content_multigroup/content_multigroup.module:126 +msgid "Type of group." +msgstr "" + +#: includes/content.admin.inc:352;677 modules/fieldgroup/fieldgroup.module:177;341 +msgid "Save" +msgstr "" + +#: includes/content.admin.inc:585;633 includes/panels/content_types/content_field.inc:101 modules/content_multigroup/content_multigroup.module:352 +msgid "Above" +msgstr "" + +#: includes/content.admin.inc:586 includes/panels/content_types/content_field.inc:102 +msgid "Inline" +msgstr "" + +#: includes/content.admin.inc:587;614;634;642 modules/content_multigroup/content_multigroup.module:353;360 +msgid "<Hidden>" +msgstr "" + +#: includes/content.admin.inc:625;668 theme/content-admin-display-overview-form.tpl.php:17 +msgid "Exclude" +msgstr "" + +#: includes/content.admin.inc:895 modules/fieldgroup/fieldgroup.module:209 +msgid "Cancel" +msgstr "" + +#: includes/content.admin.inc:1031 modules/fieldgroup/fieldgroup.module:145 +msgid "Help text" +msgstr "" + +#: includes/content.admin.inc:1081 modules/number/number.module:123 modules/text/text.module:86 +msgid "PHP code" +msgstr "" + +#: includes/content.admin.inc:1096;1109 includes/content.rules.inc:99 modules/number/number.module:130;139 modules/text/text.module:93;102 +msgid "Code" +msgstr "" + +#: includes/content.admin.inc:1110 modules/number/number.module:140 modules/text/text.module:103 +msgid "<none>" +msgstr "" + +#: includes/content.admin.inc:1111 modules/number/number.module:141 modules/text/text.module:104 +msgid "You're not allowed to input PHP code." +msgstr "" + +#: includes/content.admin.inc:1134 modules/content_multigroup/content_multigroup.module:73 +msgid "Unlimited" +msgstr "" + +#: includes/content.admin.inc:1151 modules/content_copy/content_copy.module:251 +msgid "Save field settings" +msgstr "" + +#: includes/content.rules.inc:53;276 modules/nodereference/nodereference.rules.inc:45 modules/userreference/userreference.rules.inc:47 theme/content-admin-display-overview-form.tpl.php:11 +msgid "Field" +msgstr "" + +#: includes/panels/content_types/content_field.inc:45 modules/fieldgroup/fieldgroup.panels.inc:31 modules/fieldgroup/panels/content_types/content_fieldgroup.inc:43 modules/nodereference/panels/relationships/node_from_noderef.inc:17 modules/userreference/panels/relationships/user_from_userref.inc:17 +msgid "Node" +msgstr "" + +#: modules/content_multigroup/content_multigroup.module:356 modules/fieldgroup/fieldgroup.module:266 +msgid "none" +msgstr "" + +#: modules/fieldgroup/fieldgroup.panels.inc:10;27 modules/fieldgroup/panels/content_types/content_fieldgroup.inc:14 +msgid "Content fieldgroup" +msgstr "" + +#: modules/fieldgroup/fieldgroup.panels.inc:112 modules/fieldgroup/panels/content_types/content_fieldgroup.inc:102 +msgid "Text to display if group has no data. Note that title will not display unless overridden." +msgstr "" + +#: modules/nodereference/nodereference.module:97 modules/userreference/userreference.module:94 +msgid "Default Views" +msgstr "" + +#: modules/nodereference/nodereference.module:100 modules/userreference/userreference.module:97 +msgid "Existing Views" +msgstr "" + +#: modules/nodereference/nodereference.module:122 modules/userreference/userreference.module:119 +msgid "View arguments" +msgstr "" + +#: modules/nodereference/nodereference.module:125 modules/userreference/userreference.module:122 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "" + +#: modules/nodereference/nodereference.module:216 modules/userreference/userreference.module:195 +msgid "%name: invalid input." +msgstr "" + +#: modules/nodereference/nodereference.module:358 modules/optionwidgets/optionwidgets.module:80 modules/userreference/userreference.module:284 +msgid "Select list" +msgstr "" + +#: modules/nodereference/nodereference.module:366 modules/optionwidgets/optionwidgets.module:88 modules/userreference/userreference.module:292 +msgid "Check boxes/radio buttons" +msgstr "" + +#: modules/nodereference/nodereference.module:374 modules/userreference/userreference.module:300 +msgid "Autocomplete text field" +msgstr "" + +#: modules/nodereference/nodereference.module:429 modules/userreference/userreference.module:355 +msgid "Autocomplete matching" +msgstr "" + +#: modules/nodereference/nodereference.module:432 modules/userreference/userreference.module:358 +msgid "Starts with" +msgstr "" + +#: modules/nodereference/nodereference.module:433 modules/userreference/userreference.module:359 +msgid "Contains" +msgstr "" + +#: modules/nodereference/nodereference.module:439 modules/text/text.module:317 modules/userreference/userreference.module:365 +msgid "Size of textfield" +msgstr "" + +#: modules/number/number.module:109 modules/text/text.module:72 +msgid "Allowed values" +msgstr "" + +#: modules/number/number.module:115 modules/text/text.module:78 +msgid "Allowed values list" +msgstr "" + +#: modules/number/number.module:119 modules/text/text.module:82 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "" + +#: modules/number/number.module:133 modules/text/text.module:96 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "" + +#: modules/number/number.module:141 modules/text/text.module:104 +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "" + +#: modules/number/number.module:181 modules/text/text.module:133 +msgid "@label (!name) - Allowed values" +msgstr "" + +#: modules/number/number.module:238 modules/text/text.module:157 +msgid "%name: illegal value." +msgstr "" + +#: modules/number/number.module:356 modules/text/text.module:257 +msgid "Text field" +msgstr "" + +#: modules/text/text.module:55;202 modules/userreference/userreference.module:237 +msgid "Plain text" +msgstr "" + +#: modules/text/text.module:197 modules/userreference/userreference.module:232 +msgid "Default" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/general.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/general.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..4216e68e632bb1ffe6056f08840739ff1426e910 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/general.sv.po @@ -0,0 +1,292 @@ +# $Id$ +# +# Swedish translation of Drupal (general) +# Generated from files: +# content.module,v 1.301.2.99 2009/03/05 22:58:57 karens +# content_multigroup.module,v 1.1.2.4 2008/10/22 11:02:41 yched +# nodereference.module,v 1.138.2.49 2009/03/01 14:40:35 yched +# content.crud.inc,v 1.76.2.14 2008/11/07 15:02:02 yched +# content.admin.inc,v 1.181.2.64 2009/03/01 13:48:44 yched +# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched +# content-admin-field-overview-form.tpl.php,v 1.1.2.5 2008/10/16 14:40:54 yched +# fieldgroup.module,v 1.79.2.45 2009/02/28 23:56:17 yched +# content.panels.inc,v 1.1.2.6 2008/11/03 14:12:41 yched +# content_handler_field.inc,v 1.1.2.13 2009/03/06 15:29:34 karens +# content-admin-display-overview-form.tpl.php,v 1.1.2.3 2008/10/09 20:58:26 karens +# number.module,v 1.91.2.31 2008/12/05 23:27:56 yched +# text.module,v 1.95.2.28 2008/12/30 00:00:54 yched +# content.rules.inc,v 1.1.2.4 2008/10/24 11:11:48 fago +# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched +# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched +# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens +# userreference.module,v 1.106.2.35 2009/03/01 14:40:35 yched +# optionwidgets.module,v 1.69.2.21 2008/10/25 02:04:44 yched +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - General 6.x\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-04-20 22:18+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: content.module:493 +#: modules/content_multigroup/content_multigroup.module:903 +msgid "Order" +msgstr "Ordning" + +#: content.module:1846 +#: modules/nodereference/nodereference.module:257 +msgid "Teaser" +msgstr "Förhandstitt" + +#: content.module:1850 +#: modules/nodereference/nodereference.module:252 +msgid "Full node" +msgstr "Fullständig nod" + +#: content.module:589;596;0 +#: includes/content.crud.inc:589;633 +msgid "content" +msgstr "innehåll" + +#: includes/content.admin.inc:16 +#: modules/content_copy/content_copy_export_form.tpl.php:11 +#: theme/content-admin-field-overview-form.tpl.php:12 +msgid "Name" +msgstr "Namn" + +#: includes/content.admin.inc:16 +#: modules/content_copy/content_copy_export_form.tpl.php:12 +#: theme/content-admin-field-overview-form.tpl.php:13 +msgid "Type" +msgstr "Typ" + +#: includes/content.admin.inc:16 +#: modules/fieldgroup/fieldgroup.module:152 +msgid "Description" +msgstr "Beskrivning" + +#: includes/content.admin.inc:16 +#: theme/content-admin-field-overview-form.tpl.php:14 +msgid "Operations" +msgstr "Funktioner" + +#: includes/content.admin.inc:171;197;888 +#: modules/fieldgroup/fieldgroup.module:203 +msgid "Remove" +msgstr "Ta bort" + +#: includes/content.admin.inc:244;285;315;797;978 +#: includes/content.panels.inc:49 +#: includes/views/handlers/content_handler_field.inc:56 +#: modules/content_copy/content_copy_export_form.tpl.php:10 +#: modules/fieldgroup/fieldgroup.module:111 +#: theme/content-admin-display-overview-form.tpl.php:13 +#: theme/content-admin-field-overview-form.tpl.php:10 +msgid "Label" +msgstr "Etikett" + +#: includes/content.admin.inc:344;670 +#: modules/fieldgroup/fieldgroup.module:171;335 +msgid "Save" +msgstr "Spara" + +#: includes/content.admin.inc:578;626 +#: includes/content.panels.inc:53 +#: modules/content_multigroup/content_multigroup.module:352 +msgid "Above" +msgstr "Ovanför" + +#: includes/content.admin.inc:580;607;627;635 +#: modules/content_multigroup/content_multigroup.module:353;360 +msgid "<Hidden>" +msgstr "<Gömd>" + +#: includes/content.admin.inc:618;661 +#: theme/content-admin-display-overview-form.tpl.php:17 +msgid "Exclude" +msgstr "Uteslut" + +#: includes/content.admin.inc:888 +#: modules/fieldgroup/fieldgroup.module:203 +msgid "Cancel" +msgstr "Avbryt" + +#: includes/content.admin.inc:1024 +#: modules/fieldgroup/fieldgroup.module:139 +msgid "Help text" +msgstr "Hjälptext" + +#: includes/content.admin.inc:1074 +#: modules/number/number.module:120 +#: modules/text/text.module:85 +msgid "PHP code" +msgstr "PHP-kod" + +#: includes/content.admin.inc:1089;1102 +#: includes/content.rules.inc:99 +#: modules/number/number.module:127;136 +#: modules/text/text.module:92;101 +msgid "Code" +msgstr "Kod" + +#: includes/content.admin.inc:1103 +#: modules/number/number.module:137 +#: modules/text/text.module:102 +msgid "<none>" +msgstr "<ingen>" + +#: includes/content.admin.inc:1104 +#: modules/number/number.module:138 +#: modules/text/text.module:103 +msgid "You're not allowed to input PHP code." +msgstr "Du har inte tillåtelse att mata in PHP-kod." + +#: includes/content.admin.inc:1127 +#: modules/content_multigroup/content_multigroup.module:73 +msgid "Unlimited" +msgstr "Obegränsad" + +#: includes/content.admin.inc:1144 +#: modules/content_copy/content_copy.module:251 +msgid "Save field settings" +msgstr "Spara inställningar för fält" + +#: includes/content.panels.inc:39 +#: modules/fieldgroup/fieldgroup.panels.inc:31 +msgid "Node" +msgstr "Nod" + +#: includes/content.panels.inc:40 +#: modules/fieldgroup/fieldgroup.panels.inc:32 +msgid "Node context" +msgstr "Sammanhang för nod" + +#: includes/content.rules.inc:53;266 +#: modules/nodereference/nodereference.rules.inc:45 +#: modules/userreference/userreference.rules.inc:47 +#: theme/content-admin-display-overview-form.tpl.php:11 +msgid "Field" +msgstr "Fält" + +#: modules/content_multigroup/content_multigroup.module:356 +#: modules/fieldgroup/fieldgroup.module:260 +msgid "none" +msgstr "ingen" + +#: modules/nodereference/nodereference.module:87 +#: modules/userreference/userreference.module:84 +msgid "Default Views" +msgstr "Förvald vy" + +#: modules/nodereference/nodereference.module:90 +#: modules/userreference/userreference.module:87 +msgid "Existing Views" +msgstr "Existerande vyer" + +#: modules/nodereference/nodereference.module:112 +#: modules/userreference/userreference.module:109 +msgid "View arguments" +msgstr "Argument för vy" + +#: modules/nodereference/nodereference.module:115 +#: modules/userreference/userreference.module:112 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Tillhandahåll en kommaseparerad lista av argument att skicka till vyn." + +#: modules/nodereference/nodereference.module:205 +#: modules/userreference/userreference.module:184 +msgid "%name: invalid input." +msgstr "%name: ogiltig inmatning." + +#: modules/nodereference/nodereference.module:347 +#: modules/optionwidgets/optionwidgets.module:80 +#: modules/userreference/userreference.module:273 +msgid "Select list" +msgstr "Listval" + +#: modules/nodereference/nodereference.module:355 +#: modules/optionwidgets/optionwidgets.module:88 +#: modules/userreference/userreference.module:281 +msgid "Check boxes/radio buttons" +msgstr "Kryssrutor/radioknappar" + +#: modules/nodereference/nodereference.module:363 +#: modules/userreference/userreference.module:289 +msgid "Autocomplete text field" +msgstr "Automatiskt kompletterande textfält" + +#: modules/nodereference/nodereference.module:417 +#: modules/userreference/userreference.module:343 +msgid "Autocomplete matching" +msgstr "Automatiskt kompletterande som överensstämmer" + +#: modules/nodereference/nodereference.module:420 +#: modules/userreference/userreference.module:346 +msgid "Starts with" +msgstr "Börjar med" + +#: modules/nodereference/nodereference.module:421 +#: modules/userreference/userreference.module:347 +msgid "Contains" +msgstr "Innehåller" + +#: modules/number/number.module:106 +#: modules/text/text.module:71 +msgid "Allowed values" +msgstr "Tillåtna värden" + +#: modules/number/number.module:112 +#: modules/text/text.module:77 +msgid "Allowed values list" +msgstr "Tillåtna listvärden" + +#: modules/number/number.module:116 +#: modules/text/text.module:81 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "De möjliga värdena detta fält kan innehålla. Ange ett värde per rad i formatet nyckel|etikett. Nyckeln är värdet som kommer att lagras i databasen och måste överensstämma med typen på fältet (%type). Etiketten är valfri, och om den inte anges kommer nyckeln att anges.<br />Tillåtna HTML-taggar: @tags" + +#: modules/number/number.module:130 +#: modules/text/text.module:95 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Enbart avancerat användande: PHP-kod som skall returnera en spärrad lista av tillåtna värden. Skall inte inkludera avgränsarna <?php ?>. Om detta fält är ifyllt kommer listan som returneras av denna kod att åsidosätta det tillåtna värdet i listan ovan." + +#: modules/number/number.module:138 +#: modules/text/text.module:103 +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "Denna PHP-kod angavs av en administratör och kommer att åsidosätta det tillåtna värdet ovan." + +#: modules/number/number.module:178 +#: modules/text/text.module:132 +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Tillåtna värden" + +#: modules/number/number.module:235 +#: modules/text/text.module:156 +msgid "%name: illegal value." +msgstr "%name: otillåtet värde." + +#: modules/number/number.module:353 +#: modules/text/text.module:256 +msgid "Text field" +msgstr "Textfält" + +#: modules/text/text.module:54;201 +#: modules/userreference/userreference.module:226 +msgid "Plain text" +msgstr "Ren text" + +#: modules/text/text.module:196 +#: modules/userreference/userreference.module:221 +msgid "Default" +msgstr "Standard" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-existing-field.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-existing-field.html new file mode 100644 index 0000000000000000000000000000000000000000..f12fa40e0dd04fd71bd5c18cde5646204f4c010e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-existing-field.html @@ -0,0 +1,51 @@ +<!-- $Id$ --> +<p>Die Verwendung eines Feldes über mehrere Inhaltstypen hinweg kann praktisch +sein, wenn ein Teil der Daten für mehrere Inhaltstypen relevant ist. Ein +typischer Verwendungszweck ist ein ‚Telefonnummer‘-Feld, das sowohl in den +Inhaltstypen ‚Restaurant‘ und ‚Hotel‘ verwendet wird, auch wenn Hotels und +Restaurants unterschiedlich genug sind eine eigene Feldliste zu verdienen und +damit auch ihren eigenen dedizierten Inhaltstypen.</p> + +<p>Sollte ein Feld zu mehr wie einem Inhaltstyp hinzugefügt worden sein, wird +dieses als „gemeinsam“ bezeichnet und wie „mehrere Instanzen“ betrachtet.</p> + +<p>Unten auf der <strong>Felder verwalten</strong>-Seite eines Inhaltstypen +befindet sich folgendes:</p> + +<img src="trans_path:add-existing-field.png"> + +<p>Damit eine neue Instanz eines vorhandenen Feldes zu einem Inhaltstypen +hinzugefügt werden kann, muss die folgende Information bereitgestellt +werden:</p> +<dl> + <dt><strong>Beschriftung:</strong></dt> + <dd> + Ein Name für das Feld. Diese wird in Eingabeformularen und bei der + Anzeige von Inhalten verwendet.<br/> + Alle Zeichen sind zulässig, inklusive Leerzeichen, akzentuierte und + nicht-europäische Zeichen. + </dd> + + <dt><strong>Feld:</strong></dt> + <dd> + Das gemeinsame Feld.<br/> + Ein Feld kann nicht mehr als einmal in jedem Inhaltstypen erscheinen. + Deshalb werden nur Felder, die im aktuellen Inhaltstyp nicht vorhanden + sind als „gemeinsam nutzbar“ vorgeschlagen. Sollte keins vorhanden sein, + erscheint die <strong>Vorhandes Feld hinzufügen</strong>-Option auf der + <strong>Felder verwalten</strong>-Seite dieses Inhaltstypen nicht.<br/> + Die Auswahl eines Feldes bestückt automatisch die + <strong>Beschriftung</strong> und <strong>Steuerelement</strong>-Werte mit + denen der bisherigen Feldinstanz, ermöglicht aber eine Änderung vor dem + Speichern des Formulars. + </dd> + + <dt><strong>Steuerelement:</strong></dt> + <dd> + Das Formularelement das auf Inhaltsformularen zur Eingabe von Daten in + dieses Feld verwendet wird: Texteingabe, Auswahlliste, etc...<br/> + Jeder Feldtyp hat seine eigene Liste von verfügbaren Steuerelementen. Bei + der Auswahl eines gemeinsamen Feldes, wird die Liste der auszuwählenden + Steuerelemente automatisch aktualisiert. + </dd> +</dl> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-existing-field.png b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-existing-field.png new file mode 100644 index 0000000000000000000000000000000000000000..3c5548e84070b43195b97ac335577ba24e23b905 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-existing-field.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-field.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-field.html new file mode 100644 index 0000000000000000000000000000000000000000..1aad218888e6efd3787834712217abeb785f6309 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-field.html @@ -0,0 +1,61 @@ +<!-- $Id$ --> +<p>Am Ende der <strong>Felder verwalten</strong>-Seite eines Inhaltstypen +befindet sich folgendes:</p> + +<img src="trans_path:add-new-field.png"> + +<p>Um ein neues Feld zu einem Inhaltstypen hinzuzufügen, müssen die folgenden +Informationen angegeben werden:</p> +<dl> + <dt>Beschriftung:</dt> + <dd> + Ein Name für das Feld. Diese wird in Eingabeformularen und bei der + Anzeige von Inhalten verwendet.<br/> + Alle Zeichen sind zulässig, inklusive Leerzeichen, akzentuierte und + nicht-europäische Zeichen. + </dd> + + <dt>Feldname:</dt> + <dd> + Ein maschinenlesbarer Name für das Feld. Dieser wird intern zur + Identifizierung des Feldes und Speicherung in der Datenbank verwendet. + Bei benutzerdefinierten Theming ist dies der zu verwendende Identifikator, + um sich auf dieses Feld zu beziehen.<br/> + <strong>Wichtig:</strong> Der Feldname kann nicht mehr geändert werden + sobald das Feld erstellt wurde.<br/> + Zulässige Zeichen: a-z (nicht-akzentuiert), 0-9 und der Unterstrich (_).<br/> + Die Länge des Feldnamen darf 32 Zeichen nicht überschreiten (inklusive dem + ‚field_‘-Präfix, der automatisch hinzugefügt wird - d.h. 26 verbleibende + Zeichen. + </dd> + + <dt>Feldtyp:</dt> + <dd> + Der Datentyp der in diesem Feld gespeichert werden soll.<br/> + <strong>Wichtig:</strong> Der Feldtyp kann nicht mehr geändert werden + sobald das Feld erstellt wurde.<br/> + Die verfügbaren Feldtypen hängen von den aktivierten Modulen auf der + Website ab. CCK verfügt über 6 Basis-Feldtypen: + <ul> + <li>Text</li> + <li>Ganzzahl</li> + <li>Fließkommazahl</li> + <li>Dezimalzahl</li> + <li>Beitragsreferenz</li> + <li>Benutzerreferenz</li> + </ul> + Weitere Module können zur Verwendung anderer Feldtypen wie Datum, Dateien, + Bilder... heruntergeladen werden. Nähere Information befindet sich auf der + <a href="http://www.drupal.org/project/cck" target="_blank">CCK-Projekt-Seite</a> + und in der <a href="http://drupal.org/project/Modules/category/88" target="_blank">vollständigen Liste der mit CCK verwandten Module</a>. + </dd> + + <dt>Steuerelement:</dt> + <dd> + Das Formularelement das auf Inhaltsformularen zur Eingabe von Daten in + dieses Feld verwendet wird: Texteingabe, Auswahlliste, etc...<br/> + Jeder Feldtyp hat seine eigene Liste von verfügbaren Steuerelementen. Bei + der Auswahl eines Feldtyps, wird die Liste der auszuwählenden Steuerelemente + automatisch aktualisiert. + </dd> +</dl> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-field.png b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-field.png new file mode 100644 index 0000000000000000000000000000000000000000..82d1fa59ee3efbc5728cf32e1b72981018debbfd Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-field.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-group.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-group.html new file mode 100644 index 0000000000000000000000000000000000000000..f17e90df7ae8c07dc9bbb22594192a9cd60224cd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-group.html @@ -0,0 +1,44 @@ +<!-- $Id$ --> +<p>Feldgruppen werden verwendet, um mehrere logisch zusammenhängende Felder +visuell zusammenzufassen. Dies können beispielsweise mehrere Textfelder sein, +die unterschiedliche Teile einer ‚Adresse‘ zusammenfassen. Auf +Eingabeformularen und bei der Inhaltsanzeige, werden die entsprechenden Felder +von einem HTML-Fieldset umschlossen.</p> + +<img style="vertical-align:top" src="trans_path:group-node-edit-form.png"> +<img style="vertical-align:top" src="trans_path:group-node-display.png"> + +<p>Am Ende der <strong>Felder verwalten</strong>-Seite eines Inhaltstypen +befindet sich folgendes:</p> + +<img src="trans_path:add-new-group.png"> + +<p>Um eine neue Gruppe zu einem Inhaltstypen hinzuzufügen, müssen die folgenden +Informationen angegeben werden:</p> +<dl> + <dt><strong>Beschriftung:</strong></dt> + <dd> + Ein Name für die Gruppe. Diese wird in Eingabeformularen und bei der + Anzeige von Inhalten verwendet.<br/> + Alle Zeichen sind zulässig, inklusive Leerzeichen, akzentuierte und + nicht-europäische Zeichen. + </dd> + + <dt>Gruppenname:</dt> + <dd> + Ein maschinenlesbarer Name für die Gruppe. Dieser wird intern zur + Identifizierung der Gruppe verwendet. Bei benutzerdefinierten Theming + ist dies der zu verwendende Identifikator, um sich auf diese Gruppe zu + beziehen.<br/> + <strong>Wichtig:</strong> Der Gruppenname kann nicht mehr geändert werden + sobald die Gruppe erstellt wurde.<br/> + Zulässige Zeichen: a-z (nicht-akzentuiert), 0-9 und der Unterstrich (_).<br/> + Die Länge des Gruppennamen darf 32 Zeichen nicht überschreiten (inklusive dem + ‚group_‘-Präfix, der automatisch hinzugefügt wird - d.h. 26 verbleibende + Zeichen. + </dd> +</dl> + +<p>Sobald eine Gruppe erstellt wurde, können die davon umschlossenen Felder durch die +<a href="topic:content/rearrange">Umordnung der Felder und Gruppen</a> +festgelegt werden.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-group.png b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-group.png new file mode 100644 index 0000000000000000000000000000000000000000..99ad282e375f3ed28c9f02463d347041d265a398 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new-group.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new.png b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new.png new file mode 100644 index 0000000000000000000000000000000000000000..fbacfe264ad699b1087e08b9114c8721117cc8d8 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add-new.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add.html new file mode 100644 index 0000000000000000000000000000000000000000..eed23421713740272c5e6e090e362001bae323a5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/add.html @@ -0,0 +1,16 @@ +<!-- $Id$ --> +<p>Mit den Formularelementen am Ende der <strong>Felder verwalten</strong>- +Seite können Felder und Gruppen zu Inhaltstypen hinzugefügt werden.</p> + +<img src="trans_path:add-new.png"> + +<p style="font-size:smaller">(Die <strong>Vorhandenes Feld hinzufügen</strong>- +Zeile wird nur angezeigt, wenn Felder in anderen Inhaltstypen zur Verfügung +stehen. Die <strong>Neue Gruppe hinzufügen</strong> Zeile wird nur angezeigt, +wenn das Feldgruppen-Modul aktiviert ist.)</p> +<p>Die Felder und Gruppen werden durch Anklicken des <strong>Speichern</strong>- +Buttons am Ende der Seite erstellt. Auf den nachfolgenden Seiten wird das +Formular mit den Einstellungen jedes hinzugefügten Feldes angezeigt.</p> + +<p>Weitere Details zu den erforderlichen Informationen befinden sich auf den +folgenden Seiten:</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/content.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/content.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..049006f43e79e21f4ccdfaa12d34e0fadfdc411a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/content.help.ini @@ -0,0 +1,56 @@ +; $Id$ + +[advanced help settings] +name = CCK +index name = "CCK (Content Construction Kit)" + +[manage-fields] +title = ‚Felder verwalten‘-Reiter + +[add] +title = Felder und Gruppen hinzufügen +parent = manage-fields +weight = 1 + +[add-new-field] +title = Neues Feld hinzufügen +parent = add +weight = 1 + +[add-existing-field] +title = Vorhandenes Feld hinzufügen: Ein Feld über Inhaltstypen hinweg gemeinsam nutzen +parent = add +weight = 2 + +[add-new-group] +title = Neue Gruppe hinzufügen +parent = add +weight = 3 + +[rearrange] +title = Felder und Gruppen neu anordnen +parent = manage-fields +weight = 2 + +[remove] +title = Feld aus einem Inhaltstyp entfernen +parent = manage-fields +weight = 3 + +[theme] +title = Theming von CCK-Daten in Beiträgen + +[theme-node-templates] +title = Beitragsvorlagen +parent = theme +weight = 1 + +[theme-field-templates] +title = Feldvorlagen +parent = theme +weight = 2 + +[theme-formatters] +title = Theme-Funktionen für Formatierer +parent = theme +weight = 3 diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/drag-groups.png b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/drag-groups.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ba440443a1ebe261f4a124fd409f130621fba2 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/drag-groups.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/drag-new.png b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/drag-new.png new file mode 100644 index 0000000000000000000000000000000000000000..42e8b618f121099b132a480dd04df0003cb3c907 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/drag-new.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/group-node-display.png b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/group-node-display.png new file mode 100644 index 0000000000000000000000000000000000000000..df4eb86e5a6514a9d4dfd26cb85c0e00187d2a75 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/group-node-display.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/group-node-edit-form.png b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/group-node-edit-form.png new file mode 100644 index 0000000000000000000000000000000000000000..0cdd2f882e5464ec862d6edf8da9596e96263846 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/group-node-edit-form.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/manage-fields.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/manage-fields.html new file mode 100644 index 0000000000000000000000000000000000000000..6a6347e37f908d36edbd5e266ba66ff6b5846384 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/manage-fields.html @@ -0,0 +1,4 @@ +<!-- $Id$ --> +<p>Diese Seite ermöglicht die Verwaltung der CCK-Felder in dem Inhaltstyp: +Felder und Gruppen hinzufügen, Neuanordnung der Felder, Zugriff auf ihre +Konfigurationsseiten und das Entfernen aus dem Inhaltstyp.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/rearrange.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/rearrange.html new file mode 100644 index 0000000000000000000000000000000000000000..24d41b44f0c84c436466e672a0d8e4d63e683825 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/rearrange.html @@ -0,0 +1,29 @@ +<!-- $Id$ --> +<p>Um die Reihenfolge von einem Feld zu ändern, das Drag-and-Drop-Kreuz +<img src="path:draggable.png"> in der Bezeichnungsspalte anfassen und das Feld +an einen neuen Ort in der Liste ziehen. (Ein Drag-and-Drop-Kreuz wird +angefasst, indem das Kreuz-Icon angeklickt und festgehalten wird.) Die +Änderungen werden nicht gespeichert bis am Ende der Seite der +<strong>Speichern</strong>-Button gedrückt wird.</p> + +<p>Die festgelegte Reihenfolge wird sowohl auf Eingabeformularen (beim +Erstellen oder Bearbeiten eines Beitrages) als auch bei der Inhaltsanzeige +(Anrisstext, Inhaltsseite, RSS-Einträge...) verwendet.</p> +<p>Die Reihenfolge von nicht-CCK ‚Feldern‘ wie <strong>Titel</strong> oder +<strong>Dateianhängen</strong> kann auch geändert werden. In Abhängigkeit +des ‚Feldes‘ wird dies das Eingabeformular und/oder die Inhaltsanzeige (einige +dieser ‚Felder‘ werden nicht in beiden Kontexten angezeigt) beeinflussen.</p> +<p>Sollten Gruppen in dem Inhaltstyp vorhanden sein (erfordert das Feldgruppen- +Modul), kann ein Feld in eine Gruppe verschoben werden, indem es unterhalb der +Zeile dieser Gruppe gezogen wird und dann leicht nach rechts, bevor es +losgelassen wird. Dabei ist zu beachten, dass auch Gruppen neu angeordnet +aber derzeit nicht in andere Gruppen verschachtelt werden können.</p> + +<img src="trans_path:drag-groups.png"> + +<p>Beim Hinzufügen eines Feldes oder einer Gruppe, können diese in der +angezeigten Liste von Feldern und Gruppen schon vor dem +<strong>Speichern</strong> an den gewünschten Ort im Inhaltstyp gezogen +werden:</p> + +<img src="trans_path:drag-new.png"> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/remove.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/remove.html new file mode 100644 index 0000000000000000000000000000000000000000..d640164655a58f09b0d92ed647b7fe11c7a53f0c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/remove.html @@ -0,0 +1,11 @@ +<!-- $Id$ --> +<p>Sollte ein Feld aus einem Inhaltstyp entfernt werden, werden alle darin +enthaltenen Daten <strong>permanent</strong> gelöscht. Für diese Aktion +erscheint eine Rückfrage.</p> + +<p>Danach müssen möglicherweise die Ansichten, Pathauto-Einstellungen, etc. +manuell aktualisiert werden.</p> + +<p>Hinweis: Bei gemeinsammer Nutzung des Feldes über mehrere Inhaltstypen +hinweg, wird das Entfernen aus einem Inhaltstyp die Daten der anderen +Inhaltstypen <strong>nicht</strong> beeinflussen.</p> diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/theme-formatters.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/theme-formatters.html new file mode 100644 index 0000000000000000000000000000000000000000..3571beceaba718fbc91dbed7cecd2e65600ed42d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/theme-formatters.html @@ -0,0 +1,17 @@ +<!-- $Id$ --> +<p>Formatierer werden verwendet, um die Rohdaten eines einzelnen Feldwertes in +HTML umzuwandeln. Der <strong>Felder anzeigen</strong>-Reiter erlaubt die +Auswahl eines gewünschten Formatierers für jedes der Felder.</p> + +<p>In CCK 2.0 für Drupal 6 durchlaufen alle Formatierer den Theme-Layer. +Deshalb ist das Übersteuern eines Formatierer-Themes eine weitere Möglichkeit +zur Anpassung der Anzeige von Werten (wobei die Änderung der +<span class="code">content-field.tpl.php</span> die Möglichkeit bietet das +HTML, dass die Werte „umschließt“ zu ändern).</p> + +<p>Die meisten Formatierer sind als Theme-Funktion implementiert aber einige +verwenden stattdessen auch Templates. Auf die eine oder andere Art können +diese durch die Verwendung der entsprechenden Drupal 6 Theme-Übersteuerungsmethode +übersteuert werden. Nähere Informationen gibt es auf der Handbuch-Seite zum +<a href="http://drupal.org/theme-guide">Theme-Guide für Drupal 6</a> und etwas +spezieller im Bereich zum <a href="http://drupal.org/node/173880">Überschreiben von themebarer Ausgabe</a>.</p> diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/theme.html b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/theme.html new file mode 100644 index 0000000000000000000000000000000000000000..a8312b8df71f9e5fdacad28273d57a516d48a0ce --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/help/de/theme.html @@ -0,0 +1,11 @@ +<!-- $Id$ --> +<p><strong>Hinweis:</strong> Diese Anleitungen gehen davon aus, dass eine +gewisse Vertrautheit mit den Basis-Konzepten des Drupal6-Theming vorhanden ist. +Nähere Informationen gibt es auf der Handbuch-Seite zum +<a href="http://drupal.org/theme-guide">Theme-Guide für Drupal 6</a> und etwas spezieller im +Bereich zum <a href="http://drupal.org/node/173880">Überschreiben von themebarer Ausgabe</a>.</p> + +<p>Es gibt 3 Ebenen auf denen die Daten in CCK-Feldern für die Anzeige in +Beiträgen angepasst werden können:</p> + +<img src="path:theme.png" style="border:1px solid #AAA"> diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/hu.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/hu.po new file mode 100644 index 0000000000000000000000000000000000000000..09ef51aa9dd85f2e31c6784ca4dffec13ea208b2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/hu.po @@ -0,0 +1,1541 @@ +# Hungarian translation of Content Construction Kit (CCK) (6.x-2.6) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Content Construction Kit (CCK) (6.x-2.6)\n" +"POT-Creation-Date: 2009-11-19 19:52+0000\n" +"PO-Revision-Date: 2009-11-19 18:53+0000\n" +"Language-Team: Hungarian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +msgid "CCK" +msgstr "CCK" +msgid "delete" +msgstr "törlés" +msgid "Prefix" +msgstr "Előtag" +msgid "Suffix" +msgstr "Toldalék" +msgid "Operations" +msgstr "Műveletek" +msgid "Content" +msgstr "Tartalom" +msgid "content" +msgstr "tartalom" +msgid "Type" +msgstr "Típus" +msgid "Cancel" +msgstr "Mégsem" +msgid "Remove" +msgstr "Eltávolítás" +msgid "Description" +msgstr "Leírás" +msgid "Language" +msgstr "Nyelv" +msgid "Block title" +msgstr "Blokk címe" +msgid "Taxonomy" +msgstr "Taxonómia" +msgid "Content types" +msgstr "Tartalomtípusok" +msgid "Search" +msgstr "Keresés" +msgid "None" +msgstr "Nincs" +msgid "Display settings" +msgstr "Megjelenítési beállítások" +msgid "This action cannot be undone." +msgstr "A művelet nem vonható vissza." +msgid "Number" +msgstr "Szám" +msgid "- None -" +msgstr "- Nincs -" +msgid "Weight" +msgstr "Súly" +msgid "Help text" +msgstr "Súgó szöveg" +msgid "Types" +msgstr "Típusok" +msgid "Required" +msgstr "Szükséges" +msgid "none" +msgstr "nincs" +msgid "Name" +msgstr "Név" +msgid "edit" +msgstr "szerkesztés" +msgid "Import" +msgstr "Import" +msgid "Book" +msgstr "Könyv" +msgid "Export" +msgstr "Export" +msgid "Field" +msgstr "Mező" +msgid "Label" +msgstr "Címke" +msgid "Save" +msgstr "Mentés" +msgid "Default" +msgstr "Alapértelmezés" +msgid "Add" +msgstr "Hozzáadás" +msgid "Format" +msgstr "Formátum" +msgid "Teaser" +msgstr "Bevezető" +msgid "Text" +msgstr "Szöveg" +msgid "Content type" +msgstr "Tartalomtípus" +msgid "Continue" +msgstr "Folytatás" +msgid "Configure" +msgstr "Beállítás" +msgid "Node" +msgstr "Tartalom" +msgid "Include" +msgstr "Befoglalás" +msgid "Exclude" +msgstr "Kizárás" +msgid "All" +msgstr "Minden" +msgid "View arguments" +msgstr "A nézet paraméterei" +msgid "RSS" +msgstr "RSS" +msgid "Inline" +msgstr "Beágyazó" +msgid "Delta" +msgstr "Delta" +msgid "Custom" +msgstr "Egyedi" +msgid "Poll choices" +msgstr "Poll válaszok" +msgid "Content field" +msgstr "Tartalom mező" +msgid "Field name" +msgstr "Mező neve" +msgid "Field type" +msgstr "Mező típusa" +msgid "Global settings" +msgstr "Általános beállítások" +msgid "Fields" +msgstr "Mezők" +msgid "Widget type" +msgstr "Felületi elem típusa" +msgid "Contains" +msgstr "Tartalmazza" +msgid "N/A" +msgstr "Nincs adat" +msgid "This field is required." +msgstr "Szükséges mező." +msgid "Maximum" +msgstr "Maximum" +msgid "Scale" +msgstr "Felbontás" +msgid "Plain text" +msgstr "Egyszerű szöveg" +msgid "Unlimited" +msgstr "Korlátlan" +msgid "Code" +msgstr "Kód" +msgid "Basic" +msgstr "Alap" +msgid "Filtered text (user selects input format)" +msgstr "Formázott szöveg (a felhasználó választja ki a beviteli formát)" +msgid "Text processing" +msgstr "Szövegfeldolgozás" +msgid "Maximum length" +msgstr "Maximális hossz" +msgid "" +"The maximum length of the field in characters. Leave blank for an " +"unlimited size." +msgstr "" +"A mező karakterben mért maximális hossza. Üresen hagyva nincs " +"korlátozva." +msgid "Rows" +msgstr "Sorok" +msgid "Existing Views" +msgstr "Létező nézetek" +msgid "Default Views" +msgstr "Alapértelmezett nézetek" +msgid "Empty text" +msgstr "Üres szöveg" +msgid "Order" +msgstr "Sorrend" +msgid "Integer" +msgstr "Egész szám" +msgid "Edit group" +msgstr "Csoport szerkesztése" +msgid "Size of textfield" +msgstr "A szövegmező mérete" +msgid "File attachments" +msgstr "Csatolmányok" +msgid "Token" +msgstr "Vezérjel" +msgid "Allowed values list" +msgstr "Megengedett értékek" +msgid "Select list" +msgstr "Legördülő lista" +msgid "Text field" +msgstr "Szövegmező" +msgid "PHP code" +msgstr "PHP kód" +msgid "Display fields" +msgstr "Mezők megjelenítése" +msgid "Poll settings" +msgstr "Szavazás beállításai" +msgid "Style" +msgstr "Stílus" +msgid "Your settings have been saved." +msgstr "A beállítások el lettek mentve." +msgid "Reversed" +msgstr "Fordított" +msgid "%type settings" +msgstr "%type beállításai" +msgid "Menu settings" +msgstr "Menübeállítások" +msgid "edit " +msgstr "szerkesztés " +msgid "<Hidden>" +msgstr "< Rejtett >" +msgid "Comment settings" +msgstr "Hozzászólás-beküldési beállítások" +msgid "Related content" +msgstr "Kapcsolódó tartalom" +msgid "Processing" +msgstr "Feldolgozás" +msgid "Default value" +msgstr "Alapértelmezés szerinti érték" +msgid "No content types available." +msgstr "Nincs elérhető tartalomtípus." +msgid "Simple" +msgstr "Egyszerű" +msgid "Above" +msgstr "Felette" +msgid "Number of values" +msgstr "Értékek száma" +msgid "" +"Warning! Changing this setting after data has been created could " +"result in the loss of data!" +msgstr "" +"Figyelem! Már létrehozott adatok esetén ezeknek a beállításoknak " +"a megváltoztatása az adatok elvesztésével jár!" +msgid "" +"The content module, a required component of the Content Construction " +"Kit (CCK), allows administrators to associate custom fields with " +"content types. In Drupal, content types are used to define the " +"characteristics of a post, including the title and description of the " +"fields displayed on its add and edit pages. Using the content module " +"(and the other helper modules included in CCK), custom fields beyond " +"the default \"Title\" and \"Body\" may be added. CCK features are " +"accessible through tabs on the <a href=\"@content-types\">content " +"types administration page</a>. (See the <a href=\"@node-help\">node " +"module help page</a> for more information about content types.)" +msgstr "" +"A content modul, amely egy szükséges eleme a Content Construction " +"Kitnek (CCK), lehetővé teszi az adminisztrátorok számára, hogy " +"egyedi mezőket rendeljenek a tartalomtípusokhoz. A Drupalban a " +"tartalomtípus határozza meg az oldalak jellemzőit, beleértve a " +"megjelenített mezők címét és leírását a feltöltő és " +"szerkesztő oldalakon. A content modult (és az egyéb, CCK-ba " +"ágyazott segítő modulokat) használva egyedi mezőket lehet adni az " +"alapértelmezett „Cím” és „Törzs” mezők mellé. A CCK " +"lehetőségei a <a href=\"@content-types\">tartalomtípusok " +"adminisztrációja oldalon</a> lévő füleken elérhetők el. " +"(További információk a tartalomtípusokról a <a " +"href=\"@node-help\">node modul súgó oldalán</a>.)" +msgid "" +"When adding a custom field to a content type, you determine its type " +"(whether it will contain text, numbers, or references to other " +"objects) and how it will be displayed (either as a text field or area, " +"a select box, checkbox, radio button, or autocompleting field). A " +"field may have multiple values (i.e., a \"person\" may have multiple " +"e-mail addresses) or a single value (i.e., an \"employee\" has a " +"single employee identification number). As you add and edit fields, " +"CCK automatically adjusts the structure of the database as necessary. " +"CCK also provides a number of other features, including intelligent " +"caching for your custom data, an import and export facility for " +"content type definitions, and integration with other contributed " +"modules." +msgstr "" +"Egy egyedi mező tartalomtípushoz adásakor meghatározható annak " +"típusa (attól függően, hogy mit fog tartalmazni, szöveget, " +"számot, vagy hivatkozást egyéb objektumokhoz), illetve hogyan fog " +"megjelenni (szöveges mező vagy terület, legördülő menü, " +"jelölő vagy kiválasztó négyzet, avagy automatikusan kiegészülő " +"mező). Egy mezőnek lehet több értéke is (például egy " +"„személy”-nek lehet több email címe), illetve csak egyetlen " +"értéke (például egy „dolgozó”-nak csak egy dolgozói " +"azonosítója van). A mező hozzáadásakor és szerkesztésekor a CCK " +"automatikusan elkészíti az adat tárolásához szükséges " +"szerkezetet az adatbázisban. A CCK számos egyéb lehetőséget " +"biztosít, például az egyedi adatok intelligens gyorstárazását, a " +"tartalomtípus meghatározások importálását és exportálását, " +"valamint együttműködést egyéb közösségi modulokkal." +msgid "" +"Custom field types are provided by a set of optional modules included " +"with CCK (each module provides a different type). The <a " +"href=\"@modules\">modules page</a> allows you to enable or disable CCK " +"components. A default installation of CCK includes:" +msgstr "" +"Az egyedi mező típusokat a CCK-ba ágyazott egyéb, kiegészítő " +"modulok biztosítják (minden modul más típust tesz elérhetővé). " +"A <a href=\"@modules\">modulok oldal</a> segítségével lehet be-, " +"illetve kikapcsolni a CCK összetevőit. Egy alapértelmezett " +"telepítés esetén a CCK az alábbiakat tartalmazza:" +msgid "" +"<em>number</em>, which adds numeric field types, in integer, decimal " +"or floating point form. You may define a set of allowed inputs, or " +"specify an allowable range of values. A variety of common formats for " +"displaying numeric data are available." +msgstr "" +"<em>szám</em>, amely egy numerikus mezőtípust ad, egész, " +"decimális, vagy lebegőpontos formában. Beállítható a megengedett " +"értékek csoportja, vagy megadható az elfogadott érték " +"tartományok köre. Elérhető számos közös formátum a számok " +"megjelenítéséhez." +msgid "" +"<em>text</em>, which adds text field types. A text field may contain " +"plain text only, or optionally, may use Drupal's input format filters " +"to securely manage rich text input. Text input fields may be either a " +"single line (text field), multiple lines (text area), or for greater " +"input control, a select box, checkbox, or radio buttons. If desired, " +"CCK can validate the input to a set of allowed values." +msgstr "" +"<em>szöveg</em>, amely szöveges mezőtípus ad. A szöveges mező " +"tartalmazhat csak sima szöveget, vagy beállíthatóan lehet " +"használni a Drupal bemeneti formátum szűrőit is a szövegek " +"biztonságos kezeléséhez. A szöveges mezők lehetnek egy vagy több " +"sorosak, illetve nagyobb bemeneti ellenőrzéshez legördülő menü, " +"jelölő vagy kiválasztó négyzet. Ha szükséges, a CCK tudja " +"ellenőrizni a bevitelt a megengedett értékek alapján." +msgid "" +"<em>nodereference</em>, which creates custom references between Drupal " +"nodes. By adding a <em>nodereference</em> field and two different " +"content types, for instance, you can easily create complex " +"parent/child relationships between data (multiple \"employee\" nodes " +"may contain a <em>nodereference</em> field linking to an \"employer\" " +"node)." +msgstr "" +"<em>tartalomlhivatkozás</em>, amely egyedi hivatkozásokat hoz létre " +"a Drupal oldalak között. Két különböző tartalomtípus között " +"egy <em>tartalomhivatkozás</em> mező hozzáadásával könnyedén " +"létrehozható összetett szülő-gyermek kapcsolat az adatok között " +"(több „dolgozó” oldal tartalmaz egy <em>tartalomhivatkozás</em> " +"mezőt, hivatkozva a „munkaadó” oldalra." +msgid "" +"<em>userreference</em>, which creates custom references to your sites' " +"user accounts. By adding a <em>userreference</em> field, you can " +"create complex relationships between your site's users and posts. To " +"track user involvement in a post beyond Drupal's standard <em>Authored " +"by</em> field, for instance, add a <em>userreference</em> field named " +"\"Edited by\" to a content type to store a link to an editor's user " +"account page." +msgstr "" +"<em>felhasználó hivatkozás</em>, amely egyedi hivatkozásokat hoz " +"létre a honlap felhasználóihoz. Egy <em>felhasználó " +"hivatkozás</em> mező hozzáadásával létrehozható összetett " +"szülő-gyermek kapcsolat a felhasználók és az oldalak között. A " +"tartalomtípushoz egy „Szerkesztette” <em>felhasználó " +"hivatkozás</em> mezőt adva egy hivatkozás keletkezik a szerkesztő " +"felhasználó profiljához, így követni lehet a felhasználó " +"részvételét a tartalomban a Drupal alapértelmezett <em>Írta</em> " +"mezőjén kívül is." +msgid "" +"<em>fieldgroup</em>, which creates collapsible fieldsets to hold a " +"group of related fields. A fieldset may either be open or closed by " +"default. The order of your fieldsets, and the order of fields within a " +"fieldset, is managed via a drag-and-drop interface provided by content " +"module." +msgstr "" +"<em>mezőcsoport</em>, amely egy összecsukható mezőkészletet hoz " +"létre, és egy csoportba foglalja az összetartozó mezőket. A " +"mezőkészlet alapértelmezése lehet nyitott, vagy zárt is. A " +"mezőcsoportok sorrendje, valamint a csoportokon belüli mezők " +"sorrendje fogd-és-vidd módszerrel állítható be a content " +"modulban." +msgid "" +"For more information, see the online handbook entry for <a " +"href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK " +"project page</a>." +msgstr "" +"További információ a beállítási és testreszabási kézikönyv " +"<a href=\"@handbook-cck\">CCK</a> oldalán, vagy a <a " +"href=\"@project-cck\">CCK projekt oldalán</a> érhető el." +msgid "" +"Configure how this content type's fields and field labels should be " +"displayed when it's viewed in teaser and full-page mode." +msgstr "" +"A tartalomtípus mezőinek és címkéinek megjelenítési " +"beállítása, amikor megtekintik előnézeti és teljes oldal " +"módban." +msgid "" +"Configure how this content type's fields should be displayed when it's " +"rendered in the following contexts." +msgstr "" +"A tartalomtípus mezőinek megjelenítési beállítása, amikor meg " +"kell jelenniük a következő környezetben." +msgid "!title: !required" +msgstr "!title: !required" +msgid "Add another item" +msgstr "Újabb elem hozzáadása" +msgid "Full node" +msgstr "Teljes tartalom" +msgid "Search Index" +msgstr "Keresés index" +msgid "Search Result" +msgstr "Keresés eredménye" +msgid "Updating field type %type with module %module." +msgstr "%type mezőtípus módosítása %module modulnál." +msgid "Updating widget type %type with module %module." +msgstr "%type felületi elemtípus módosítása %module modulnál." +msgid "Manage fields" +msgstr "Mezők kezelése" +msgid "Remove field" +msgstr "Mező törlése" +msgid "Allows administrators to define new content types." +msgstr "" +"Lehetőséget ad az adminisztrátorok számára új tartalomtípusok " +"meghatározására." +msgid "" +"Advanced usage only: PHP code that returns a keyed array of allowed " +"values. Should not include <?php ?> delimiters. If this field is " +"filled out, the array returned by this code will override the allowed " +"values list above." +msgstr "" +"Csak haladóknak: PHP kód, ami visszaadja a megengedett értékek " +"tömbjét. Nem szükséges <?php ?> elemek közé zárni. Ha ez " +"a mező ki van töltve, a kód által visszaadott tömb felülír " +"minden fentebb megadott értéket." +msgid "Trimmed" +msgstr "Levágva" +msgid "Used in" +msgstr "Ez használja" +msgid "No fields have been defined for any content type yet." +msgstr "Egyetlen tartalomtípushoz sincs még mező hozzárendelve." +msgid "no styling" +msgstr "formázás nélkül" +msgid "simple" +msgstr "egyszerű" +msgid "fieldset" +msgstr "mezőcsoport" +msgid "fieldset - collapsible" +msgstr "mezőcsoport - összecsukható" +msgid "fieldset - collapsed" +msgstr "mezőcsoport - összecsukva" +msgid "Added field %label." +msgstr "%label mező hozzáadva." +msgid "There was a problem adding field %label." +msgstr "A mező hozzáadásánál hiba történt: %label." +msgid "There was a problem creating field %label." +msgstr "Hiba történt a mező létrehozásakor: %label." +msgid "Are you sure you want to remove the field %field?" +msgstr "„%field” mező biztosan eltávolítható?" +msgid "" +"If you have any content left in this field, it will be lost. This " +"action cannot be undone." +msgstr "" +"Ha bármilyen adatot tartalmaz ez a mező, az el fog veszni. Ezt a " +"műveletet nem lehet visszavonni." +msgid "Removed field %field from %type." +msgstr "A mező törölve lett: %field (%type tartalomtípusból)." +msgid "There was a problem deleting %field from %type." +msgstr "" +"Hiba történt a mező (%label) %type tartalomtípusból való " +"törlése közben." +msgid "" +"These settings apply only to the %field field as it appears in the " +"%type content type." +msgstr "" +"Ezek a mezőn (%field) végzett beállítások csak ebben a " +"tartalomtípusban jelennek meg: %type." +msgid "" +"These settings apply to the %field field in every content type in " +"which it appears." +msgstr "" +"Ezek a mezőn (%field) végzett beállítások minden olyan " +"tartalomtípusban megjelennek, amelyben a mező megjelenik." +msgid "Save field settings" +msgstr "Mező beállításainak mentése" +msgid "" +"The default value PHP code returned an incorrect value.<br/>Expected " +"format: <pre>!sample</pre> Returned value: @value" +msgstr "" +"Az alapértelmezett értéket adó PHP kód érvénytelen értéket ad " +"vissza.<br />Elvárt formátum: <pre>!sample</pre> Visszaadott " +"érték: @value" +msgid "The default value is invalid." +msgstr "Az alapértelmezett érték érvénytelen" +msgid "Saved field %label." +msgstr "%label mező el lett mentve." +msgid "The update has encountered an error." +msgstr "A frissítés során hiba történt." +msgid "The database has been altered and data has been migrated or deleted." +msgstr "" +"Az adatbázis megváltozott és az adatok átemelve vagy törölve " +"lettek." +msgid "An error occurred and database alteration did not complete." +msgstr "" +"Hiba történt és az adatbázis megváltoztatása nem fejeződött " +"be." +msgid "Processing %title" +msgstr "%title feldolgozása" +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "1 elem sikeresen fel lett dolgozva:" +msgstr[1] "@count elem sikeresen fel lett dolgozva:" +msgid "" +"Content fields table %old_name has been renamed to %new_name and field " +"instances have been updated." +msgstr "" +"%old_name új neve %new_name a tartalom mezők táblában, és a mező " +"előfordulási helyei frissítve lettek." +msgid "The content fields table %name has been deleted." +msgstr "A tartalom mezők %name táblája törölve lett." +msgid "Referenced node ID" +msgstr "Hivatkozott tartalom azonosítója" +msgid "Referenced node title" +msgstr "Hivatkozott tartalom cím" +msgid "Raw number value" +msgstr "Nyers szám érték" +msgid "Formatted number value" +msgstr "Formázott szám" +msgid "Raw, unfiltered text" +msgstr "Nyers, formázatlan szöveg" +msgid "Formatted and filtered text" +msgstr "Formázott és szűrt szöveg" +msgid "Referenced user ID" +msgstr "A hivatkozott felhasználó azonosítója." +msgid "Referenced user name" +msgstr "A hivatkozott felhasználó neve." +msgid "Formatted HTML link to referenced user" +msgstr "HTML hivatkozás a hivatkozott felhasználóra" +msgid "Group multiple values" +msgstr "Többszörös értékek csoportosítása" +msgid "Select the content type to export." +msgstr "Tartalomtípus kiválasztása az exporthoz." +msgid "Export data" +msgstr "Adatok exportálása" +msgid "" +"Copy the export text and paste it into another content type using the " +"import function." +msgstr "" +"Az export által előállított szöveget át lehet másolni egy " +"másik tartalomtípusba az import művelet segítségével." +msgid "" +"This form will import field definitions exported from another content " +"type or another database.<br/>Note that fields cannot be duplicated " +"within the same content type, so imported fields will be added only if " +"they do not already exist in the selected type." +msgstr "" +"Ez az űrlap importálja a mező meghatározásokat, melyek egy másik " +"tartalomtípusból, vagy egy másik adatbázisból lettek " +"exportálva.<br>Megjegyzés: Egy tartalomtípuson belül a mezőket " +"nem lehet többszörözni, így csak azok a mezők lesznek hozzáadva, " +"melyek még nem szerepelnek a kiválasztott tartalomtípusban." +msgid "<Create>" +msgstr "< Létrehozás >" +msgid "" +"Select the content type to import these fields into.<br/>Select " +"<Create> to create a new content type to contain the fields." +msgstr "" +"Tartalomtípus kiválasztása a mezők importálásához.<br>A " +"<Létrehozás> segítségével új tartalomtípus jön létre, " +"mely tartalmazni fogja a mezőket." +msgid "Import data" +msgstr "Adatok importálása" +msgid "Paste the text created by a content export into this field." +msgstr "" +"A tartalom exportnál keletkezett szöveget kell ebbe a mezőbe " +"illeszteni." +msgid "The import data is not valid import text." +msgstr "Az adat nem értelmezhető import szövegként." +msgid "" +"The following modules must be enabled for this import to work: " +"%modules." +msgstr "" +"A következő modulokat engedélyezni kell, hogy ez az import " +"működjön: %modules." +msgid "The content type %type already exists in this database." +msgstr "%type tartalomtípus már szerepel az adatbázisban." +msgid "Exiting. No import performed." +msgstr "Kilépés. Az importálás nem lett végrehajtva." +msgid "" +"An error has occurred adding the content type %type.<br/>Please check " +"the errors displayed for more details." +msgstr "" +"Hiba történt a következő tartalomtípus hozzáadása közben: " +"%type.<br />További részletek a megjelenített hibaüzenetekben." +msgid "" +"The imported field %field_label (%field_name) was not added to %type " +"because that field already exists in %type." +msgstr "" +"%field_label (%field_name) mező már létezik, ezért az import " +"során nem lett hozzáadva a következő tartalomtípushoz: %type." +msgid "" +"The field %field_label (%field_name) was added to the content type " +"%type." +msgstr "" +"%field_label (%field_name) mező hozzá lett adva a következő " +"tartalomtípushoz: %type." +msgid "" +"An error occurred when exporting the 'display settings' data for the " +"field %field_name.<br/>The db error is: '%db_err'." +msgstr "" +"%field_name mező „Megjelenítési beállítás” adatainak " +"exportálása közben egy hiba keletkezett. <br />Az adatbázis hiba: " +"„%db_err”." +msgid "Content Copy" +msgstr "Content Copy" +msgid "Enables ability to import/export field definitions." +msgstr "" +"Lehetővé teszi a meződefiníciók importálását és " +"exportálását." +msgid "field_name" +msgstr "field_name" +msgid "view " +msgstr "nézet " +msgid "" +"Please <a href=\"!url\">configure your field permissions</a> " +"immediately. All fields are inaccessible by default." +msgstr "" +"Érdemes azonnal <a href=\"!url\">beállítani a mezők " +"jogosultságait</a>. Alapértelmezés szerint egyik mező sem érhető " +"el." +msgid "Content Permissions" +msgstr "Content Permissions" +msgid "Set field-level permissions for CCK fields." +msgstr "Mezőszintű jogosultságok beállítása." +msgid "These settings apply to the group in the node editing form." +msgstr "" +"Ezek a beállítások lesznek értelmezve a csoportra a " +"tartalomszerkesztő űrlapon." +msgid "always open" +msgstr "mindig nyitott" +msgid "collapsible" +msgstr "összecsukható" +msgid "collapsed" +msgstr "összecsukott" +msgid "Instructions to present to the user on the editing form." +msgstr "Az űrlap szerkesztésekor megjelenő útmutató." +msgid "These settings apply to the group on node display." +msgstr "" +"Ezek a beállítások lesznek értelmezve a csoportra a tartalom " +"megjelenítésekor." +msgid "A description of the group." +msgstr "A csoport leírása." +msgid "Are you sure you want to remove the group %label?" +msgstr "%label csoport biztosan törölhető?" +msgid "The group %group_name has been removed." +msgstr "%group_name csoport törölve lett." +msgid "Fieldgroup" +msgstr "Mezőcsoport" +msgid "Node reference" +msgstr "Tartalomra hivatkozás" +msgid "Store the ID of a related node as an integer value." +msgstr "A hivatkozott tartalom azonosítójának tárolása egész számként." +msgid "Content types that can be referenced" +msgstr "Tartalomtípusok, melyekre hivatkozni lehet" +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Haladó - tartalmak, melyekre hivatkozni lehet (Nézet)" +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "" +"Vesszővel elválasztott lista, amely a nézetnek küldendő " +"paramétereket tartalmazza." +msgid "Title (link)" +msgstr "Cím (hivatkozással)" +msgid "Title (no link)" +msgstr "Cím (hivatkozás nélkül)" +msgid "Autocomplete text field" +msgstr "Automatikusan kiegészülő szöveges mező" +msgid "Nodereference autocomplete" +msgstr "Automatikusan kiegészülő tartalomhivatkozás" +msgid "Node Reference" +msgstr "Node Reference" +msgid "Defines a field type for referencing one node from another." +msgstr "" +"Olyan mezőtípust ad, amely a tartalomban egy másik tartalomra " +"hivatkozik." +msgid "Store a number in the database as an integer." +msgstr "Egészként tárol számot az adatbázisban." +msgid "Decimal" +msgstr "Decimális" +msgid "Store a number in the database in a fixed decimal format." +msgstr "Rögzített tízes számot tárol az adatbázisban" +msgid "Float" +msgstr "Lebegőpontos" +msgid "Store a number in the database in a floating point format." +msgstr "Lebegőpontos számot tárol az adatbázisban." +msgid "Minimum" +msgstr "Minimum" +msgid "Precision" +msgstr "Pontosság" +msgid "" +"The total number of digits to store in the database, including those " +"to the right of the decimal." +msgstr "" +"Az adatbázisban tárolt számjegyek teljes száma, beleértve a " +"tizedesponttól jobbra lévő számjegyeket is." +msgid "The number of digits to the right of the decimal." +msgstr "A számjegyek száma." +msgid "Decimal marker" +msgstr "Decimális jelölő" +msgid "The character users will input to mark the decimal point in forms." +msgstr "Az űrlapokon a tizedespont jelölésére használt karakter." +msgid "" +"Define a string that should be prefixed to the value, like $ or €. " +"Leave blank for none. Separate singular and plural values with a pipe " +"(pound|pounds)." +msgstr "" +"Egy karaktersorozat, ami az érték előtagja lehet, mint például a " +"$ vagy az €. Ha nincs előtag, akkor üresen kell hagyni. " +"Függőleges vonallal lehet elválasztani egymástól az egyes és a " +"többes számú alakot (font|fontok)." +msgid "" +"Define a string that should suffixed to the value, like m², m/s², " +"kb/s. Leave blank for none. Separate singular and plural values with a " +"pipe (pound|pounds)." +msgstr "" +"Egy karaktersorozat, ami az érték toldaléka lehet, mint például " +"m², m/s², kb/s. Ha nincs toldalék, akkor üresen kell hagyni. " +"Függőleges vonallal lehet elválasztani egymástól az egyes és a " +"többes számú alakot (font|fontok)." +msgid "Allowed values" +msgstr "Megengedett értékek" +msgid "\"Minimum\" must be a number." +msgstr "„Minimum”-nak számot kell megadni." +msgid "\"Maximum\" must be a number." +msgstr "„Maximum”-nak számot kell megadni." +msgid "unformatted" +msgstr "formázatlan" +msgid "Defines numeric field types." +msgstr "Numerikus mezőtípusokat határoz meg." +msgid "" +"For a 'single on/off checkbox' widget, define the 'off' value first, " +"then the 'on' value in the <strong>Allowed values</strong> section. " +"Note that the checkbox will be labeled with the label of the 'on' " +"value." +msgstr "" +"Az „egyszerű jelölőnégyzet” felületi elemnél először a " +"„ki”, majd a „be” állapothoz tartozó értéket kell megadni " +"az <strong>Engedélyezett értékek</strong> részben. A " +"jelölőnégyzet címkéje a „be” állapothoz tartozó érték " +"címkéje lesz." +msgid "" +"The 'checkboxes/radio buttons' widget will display checkboxes if the " +"multiple values option is selected for this field, otherwise radios " +"will be displayed." +msgstr "" +"A „Jelölőnégyzetek/választógombok” felületi elem " +"jelölőnégyzeteket jelenít meg, ha a mezőnek több értéke is " +"lehet, különben választógombok jelennek meg." +msgid "Check boxes/radio buttons" +msgstr "Jelölőnégyzetek/választógombok" +msgid "Single on/off checkbox" +msgstr "Egyszerű be/ki jelölőnégyzet" +msgid "Option Widgets" +msgstr "Option Widgets" +msgid "" +"Defines selection, check box and radio button widgets for text and " +"numeric fields." +msgstr "" +"A szöveg és szám mezőtípushoz legördülő lista, " +"jelölőnégyzet és választógomb típusú felületi elemeket ad." +msgid "Store text in the database." +msgstr "Szöveget tárol az adatbázisban." +msgid "Text area (multiple rows)" +msgstr "Szövegdoboz (többsoros)" +msgid "Defines simple text field types." +msgstr "Egyszerű szöveges mező típusokat határoz meg." +msgid "User reference" +msgstr "Hivatkozás felhasználóra" +msgid "Store the ID of a related user as an integer value." +msgstr "" +"A hivatkozott felhasználó azonosítójának tárolása egész " +"számként." +msgid "User roles that can be referenced" +msgstr "Felhasználói csoport, amelyre hivatkozni lehet" +msgid "User status that can be referenced" +msgstr "Felhasználói állapot, amelyre hivatkozni lehet" +msgid "Reverse link" +msgstr "Visszamutató hivatkozás" +msgid "" +"If selected, a reverse link back to the referencing node will " +"displayed on the referenced user record." +msgstr "" +"Ha be van jelölve, akkor a felhasználó adatlapján egy hivatkozás " +"visszamutat a hivatkozó tartalomra." +msgid "Userreference autocomplete" +msgstr "Felhasználóhivatkozás automatikus kiegészítéssel" +msgid "User Reference" +msgstr "User Reference" +msgid "Defines a field type for referencing a user from a node." +msgstr "Olyan mezőtípus, amely a tartalomban egy felhasználóra hivatkozik." +msgid "All users" +msgstr "Minden felhasználó" +msgid "Active users" +msgstr "Aktív felhasználók" +msgid "Print" +msgstr "Nyomtatás" +msgid "Locked" +msgstr "Zárolt" +msgid "" +"Instructions to present to the user below this field on the editing " +"form.<br />Allowed HTML tags: @tags" +msgstr "" +"A felhasználók számára az űrlap szerkesztéskor a mező alatt " +"megjelenő útmutató.<br />Megengedett HTML elemek: @tags" +msgid "<none>" +msgstr "<nincs>" +msgid "You're not allowed to input PHP code." +msgstr "Nem engedélyezett a PHP kód bevitele." +msgid "" +"This PHP code was set by an administrator and will override any value " +"specified above." +msgstr "" +"Ezt a PHP kódot egy adminisztrátor állította be, és ez felül fog " +"írni minden fentebb megadott értéket." +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "" +"PHP alapú bevitel használata a mező beállításaihoz. (Veszélyes " +"– engedélyezésével körültekintően kell eljárni!)" +msgid "A file has been pre-loaded for import." +msgstr "A fájl előzetesen be lett töltve az importhoz." +msgid "Content fieldgroup" +msgstr "Tartalom mezőcsoport" +msgid "" +"Text to display if group has no data. Note that title will not display " +"unless overridden." +msgstr "" +"Megjelenítendő szöveg, ha a csoportnak nincs adata. A cím nem " +"jelenik meg, ha nincs felülírva." +msgid "Node from reference" +msgstr "Tartalom a hivatkozásból" +msgid "" +"Adds a node from a node reference in a node context; if multiple nodes " +"are referenced, this will get the first referenced node only." +msgstr "" +"Hozzáad egy tartalmat a tartalom hivatkozásból a tartalom " +"környezetben. Ha több tartalom van hivatkozva, csak az első " +"hivatkozott tartalmat fogja venni." +msgid "Node reference field" +msgstr "Tartalom hivatkozás mező" +msgid "" +"The possible values this field can contain. Enter one value per line, " +"in the format key|label. The key is the value that will be stored in " +"the database, and it must match the field storage type (%type). The " +"label is optional, and the key will be used as the label if no label " +"is specified.<br />Allowed HTML tags: @tags" +msgstr "" +"A mező lehetséges értékei. Egy sorban egy értéket lehet megadni " +"kulcs|címke formában. A kulcs értéke kerül az adatbázisba, és " +"ennek meg kell felelnie az adatbázisban tárolt típussal (%type). A " +"címke megadása nem kötelező, ha nincs megadva, akkor a kulcs lesz " +"a címke.<br />Az engedélyezett HTML elemek: @tags" +msgid "" +"This PHP code was set by an administrator and will override the " +"allowed values list above." +msgstr "" +"Ezt a PHP kódot egy adminisztrátor állította be, és felül fogja " +"írni a fentebb megadott elfogadható értékek listáját." +msgid "User from reference" +msgstr "Felhasználó a hivatkozásból" +msgid "" +"Adds a user from a user reference in a node context; if multiple users " +"are referenced, this will get the first referenced user only." +msgstr "" +"Hozzáad egy felhasználót a felhasználó hivatkozásból a tartalom " +"környezetben. Ha több felhasználó van hivatkozva, csak az első " +"hivatkozott felhasználót fogja venni." +msgid "User reference field" +msgstr "Felhasználó hivatkozás mező" +msgid "Show @count value(s)" +msgstr "@count értéket mutat" +msgid "starting from @count" +msgstr "@count értékről kezdve" +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - engedélyezett értékek" +msgid "%name: illegal value." +msgstr "%name: érvénytelen érték." +msgid "%name: the value may not be longer than %max characters." +msgstr "%name: az érték nem lehet hosszabb %max karakternél." +msgid "Autocomplete matching" +msgstr "Automatikus kiegészítés módja" +msgid "Starts with" +msgstr "Ezzel kezdődik" +msgid "Load a referenced user" +msgstr "Egy hivatkozott felhasználó betöltése" +msgid "Content containing the user reference field" +msgstr "A felhasználóhivatkozás mező tartalma" +msgid "Referenced user" +msgstr "Hivatkozott felhasználó" +msgid "Load a referenced node" +msgstr "Egy hivatkozott tartalom betöltése" +msgid "Content containing the node reference field" +msgstr "A tartalom, amely a hivatkozó mezőt tartalmazza" +msgid "Referenced content" +msgstr "Hivatkozott tartalom" +msgid "Populate a field" +msgstr "Egy mező feltöltése" +msgid "Select the machine-name of the field." +msgstr "A mező programok által kezelt nevének kiválasztása." +msgid "Revision information" +msgstr "Változatinformáció" +msgid "" +"Select the method used to collect autocomplete suggestions. Note that " +"<em>Contains</em> can cause performance issues on sites with thousands " +"of users." +msgstr "" +"Az automatikus kiegészítés ajánlási módjának kiválasztása. " +"Megjegyzendő, hogy a <em>Tartalmazza</em> lehetőség kiválasztása " +"teljesítmény problémákat okozhat olyan webhelyeken, melyek sokezer " +"tartalommal rendelkeznek." +msgid "View used to select the nodes" +msgstr "Nézet használata a tartalmak kiválasztásához" +msgid "%name: this post can't be referenced." +msgstr "%name: erre a tartalomra nem lehet hivatkozni." +msgid "Node module form." +msgstr "<em>Node</em> modul űrlapja." +msgid "Locale module form." +msgstr "<em>Locale</em> modul űrlapja." +msgid "Taxonomy module form." +msgstr "<em>Taxonomy</em> modul űrlapja." +msgid "Poll title" +msgstr "Poll cím" +msgid "%name: this field cannot hold more than @count values." +msgstr "%name: ez a mező nem tartalmazhat több, mint @count értéket." +msgid "'@column' => value for @column" +msgstr "„@column” => @column értéke" +msgid "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" +msgstr "" +"return array(\n" +" 0 => array(@columns),\n" +" // Itt gyakran vége is van. Több értéket is meg lehet adni\n" +" // ha az „alapértelmezett értéknek” több értéke is " +"lehet:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" +msgid "" +"Create a list of options as a list in <strong>Allowed values " +"list</strong> or as an array in PHP code. These values will be the " +"same for %field in all content types." +msgstr "" +"A választható értékek megadása az <strong>Engedélyezett " +"értékek</strong> mezőben, vagy egy PHP kóddal előállított " +"tömbben. Erre a mezőre (%field) vonatkozóan ezek az értékek " +"minden tartalomtípusnál megegyeznek." +msgid "You need to specify the 'allowed values' for this field." +msgstr "Ki kell tölteni a „Megengedett értékek”-et ennél a mezőnél." +msgid "Change basic information" +msgstr "Alapadatok megváltoztatása" +msgid "Fieldset" +msgstr "Mezőcsoport" +msgid "Translation settings" +msgstr "Fordítási beállítások" +msgid "" +"Select the method used to collect autocomplete suggestions. Note that " +"<em>Contains</em> can cause performance issues on sites with thousands " +"of nodes." +msgstr "" +"Az automatikus kiegészítés ajánlási módjának kiválasztása. " +"Megjegyzendő, hogy a <em>Tartalmazza</em> lehetőség kiválasztása " +"teljesítmény problémákat okozhat olyan webhelyeken, melyek sokezer " +"tartalommal rendelkeznek." +msgid "%name: title mismatch. Please check your selection." +msgstr "%name: a cím nem egyezik." +msgid "Path settings" +msgstr "Útvonal beállítások" +msgid "%name: the value may be no smaller than %min." +msgstr "%name: az érték nem lehet kisebb ennél: %min." +msgid "%name: the value may be no larger than %max." +msgstr "%name: az érték nem lehet nagyobb ennél: %max." +msgid "%name: found no valid user with that name." +msgstr "%name: nincs érvényes felhasználó evvel a névvel." +msgid "Field label" +msgstr "Mező cimkéje" +msgid "Form settings" +msgstr "Űrlap beállításai" +msgid "Type of group." +msgstr "A csoport típusa." +msgid "" +"If unchecked, each item in the field will create a new row, which may " +"appear to cause duplicates. This setting is not compatible with " +"click-sorting in table displays." +msgstr "" +"Ha nincs bejelölve, akkor minden elem a mezőben új sort hoz létre, " +"mely duplikációk megjelenését okozhatja. Ez a beállítás nem " +"fér össze a kattintásos rendezéssel a táblázatos megjelenésben." +msgid "" +"Some updates are still pending. Please return to <a " +"href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "" +"Néhány frissítés még függőben van. Vissza kell térni az <a " +"href=\"@update-php\">update.php</a> oldalra és a fennmaradó " +"frissítéseket le kell futtatni." +msgid "Some updates are still pending.<br/>Please re-run the update script." +msgstr "" +"Néhány frissítés még függőben van.<br />A frissítő programot " +"újra kell futtatni." +msgid "Comment module form." +msgstr "<em>Comment</em> modul űrlapja." +msgid "Translation module form." +msgstr "<em>Translation</em> modul űrlapja." +msgid "Menu module form." +msgstr "<em>Menu</em> modul űrlapja." +msgid "Book module form." +msgstr "<em>Book</em> modul űrlapja." +msgid "Path module form." +msgstr "<em>Path</em> modul űrlapja." +msgid "Poll module title." +msgstr "Poll modul cím." +msgid "Poll module choices." +msgstr "Poll modul válaszok" +msgid "Poll module settings." +msgstr "Poll modul beállítások" +msgid "Upload module form." +msgstr "<em>Upload</em> modul űrlapja." +msgid "" +"Updates for CCK-related modules are not run until the modules are " +"enabled on the <a href=\"@admin-modules-path\">administer modules " +"page</a>. When you enable them, you'll need to return to <a " +"href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "" +"A <em>CCK</em> modulokhoz kapcsolódó frissítések addig nem futnak, " +"amíg a modulok nincsenek engedélyezve a <a " +"href=\"@admin-modules-path\">modulok adminisztrációs oldalán</a>. " +"Az engedélyezés után vissza kell térni az <a " +"href=\"@update-php\">update.php</a> oldalra és a maradék " +"frissítéseket le kell futtatni." +msgid "" +"!module.module has updates but cannot be updated because " +"content.module is not enabled.<br />If and when content.module is " +"enabled, you will need to re-run the update script. You will continue " +"to see this message until the module is enabled and updates are run." +msgstr "" +"!module modulnak vannak frissítései, de nem lehet frissíteni mert a " +"content modul nincs engedélyezve.<br />Ha a content modul " +"engedélyezetté válik, akkor újra kell futtatni a frissítési " +"programot. Folyamatosan ez az üzenet fog megjelenni, amíg a modul " +"nem engedélyezett, és a frissítések futnak." +msgid "" +"!module.module has updates and is available in the modules folder but " +"is not enabled.<br />If and when it is enabled, you will need to " +"re-run the update script. You will continue to see this message until " +"the module is enabled and updates are run." +msgstr "" +"!module modulnak vannak frissítései, mely elérhető a modul " +"könytárában, de az nem engedélyezett.<br />Ha a modul " +"engedélyezetté válik, akkor újra kell futtatni a frissítési " +"programot. Folyamatosan ez az üzenet fog megjelenni, amíg a modul " +"nem engedélyezett, és a frissítések futnak." +msgid "CCK - No Views integration" +msgstr "CCK - Views-illesztés nélkül" +msgid "" +"CCK integration with Views module requires Views 6.x-2.0-rc2 or " +"greater." +msgstr "" +"CCK-Views illesztéssel, mely annak 6.x-2.0-rc2 vagy újabb " +"változatát igényli." +msgid "manage fields" +msgstr "mezők szerkesztése" +msgid "» Add a new content type" +msgstr "» Új tartalomtípus hozzáadása" +msgid "@field_name (Locked)" +msgstr "@field_name (Zárolt)" +msgid "" +"This content type has inactive fields. Inactive fields are not " +"included in lists of available fields until their modules are enabled." +msgstr "" +"Ebben a tartalomtípusban inaktív mezők vannak. Az inaktív mezők " +"nem lesznek benne az elérhető mezők listájában mindaddig, amíg a " +"számukra szükséges modulok nincsenek engedélyezve." +msgid "" +"!field (!field_name) is an inactive !field_type field that uses a " +"!widget_type widget." +msgstr "" +"!field (!field_name) egy inaktív !field_type mező, ami !widget_type " +"felületi elemet használ." +msgid "- Select a field type -" +msgstr "- Mezőtípus kiválasztása -" +msgid "- Select a widget -" +msgstr "- Felületi elem kiválasztása -" +msgid "Field name (a-z, 0-9, _)" +msgstr "Mező neve (a-z, 0-9, _)" +msgid "Type of data to store." +msgstr "A tárolandó adat típusa." +msgid "Form element to edit the data." +msgstr "Ürlap elem az adat szerkesztéséhez." +msgid "- Select an existing field -" +msgstr "- Létező mező kiválasztása -" +msgid "Field to share" +msgstr "Mező megosztása" +msgid "Group name (a-z, 0-9, _)" +msgstr "Csoport neve (a-z, 0-9, _)" +msgid "Add new field: you need to provide a label." +msgstr "Új mező hozzáadása: meg kell adni egy címkét." +msgid "Add new field: you need to provide a field name." +msgstr "Új mező hozzáadása: meg kell adni egy mezőnevet." +msgid "" +"Add new field: the field name %field_name is invalid. The name must " +"include only lowercase unaccentuated letters, numbers, and " +"underscores." +msgstr "" +"Új mező hozzáadása: %field_name mezőnév érvénytelen. A név " +"csak ékezet nélküli kisbetűket, számokat és aláhúzásjeleket " +"tartalmazhat." +msgid "" +"Add new field: the field name %field_name is too long. The name is " +"limited to 32 characters, including the 'field_' prefix." +msgstr "" +"Új mező hozzáadása: a %field_name mezőnév túl hosszú. A név " +"csak 32 karakter hosszú lehet, beleértve a „field_” előtagot " +"is." +msgid "Add new field: the name 'field_instance' is a reserved name." +msgstr "Új mező hozzáadása: a „field_instance” egy fenntartott név." +msgid "Add new field: the field name %field_name already exists." +msgstr "Új mező hozzáadása: %field_name nevű mező már létezik." +msgid "Add new field: you need to select a field type." +msgstr "Új mező hozzáadása: ki kell választani egy mezőtípust." +msgid "Add new field: you need to select a widget." +msgstr "Új mező hozzáadása: ki kell választani egy felületi elemet." +msgid "Add new field: invalid widget." +msgstr "Új mező hozzáadása: érvénytelen felületi elem." +msgid "Add existing field: you need to provide a label." +msgstr "Létező mező hozzáadása: meg kell adni egy címkét." +msgid "Add existing field: you need to select a field." +msgstr "Létező mező hozzáadása: ki kell választani egy mezőt." +msgid "Add existing field: you need to select a widget." +msgstr "Létező mező hozzáadása: ki kell választani egy felületi elemet." +msgid "Add existing field: invalid widget." +msgstr "Létező mező hozzáadása: érvénytelen felületi elem." +msgid "" +"The field %label cannot be added to a content type because it is " +"locked." +msgstr "%label mezőt nem lehet egy tartalomtípushoz sem adni, mert zárolt." +msgid "" +"There are no fields configured for this content type. You can add new " +"fields on the <a href=\"@link\">Manage fields</a> page." +msgstr "" +"Nincsenek mezők beállítva ebben a tartalomtípusban. Új mezőket " +"hozzáadni a <a href=\"@link\">Mezők kezelése</a> oldalon lehet." +msgid "@type: @field (@label)" +msgstr "@type: @field (@label)" +msgid "Edit basic information" +msgstr "Alapadatok szerkesztése" +msgid "The machine-readable name of the field. This name cannot be changed." +msgstr "" +"A mező programok által kezelt neve. Ezt a nevet nem lehet " +"megváltoztatni." +msgid "" +"A human-readable name to be used as the label for this field in the " +"%type content type." +msgstr "" +"Az emberek számára olvasható név, mint a mező címkéje lesz " +"felhasználva a %type tartalomtípusban." +msgid "" +"The type of data you would like to store in the database with this " +"field. This option cannot be changed." +msgstr "" +"A mezőben megadott adat tárolásához szükséges típus az " +"adatbázisban. Ezt a beállítást nem lehet megváltoztatni." +msgid "" +"The type of form element you would like to present to the user when " +"creating this field in the %type content type." +msgstr "" +"Az űrlapelem típusa, amely megjeleníti ezt a mezőt a felhasználó " +"számára ebben a tartalomtípusban: %type." +msgid "Updated basic settings for field %label." +msgstr "%label mező alapvető értékei módosultak." +msgid "There was a problem updating the basic settings for field %label." +msgstr "" +"Hiba történt a mező (%label) alapvető értékeinek módosítása " +"közben." +msgid "This field is <strong>locked</strong> and cannot be removed." +msgstr "Ez a mező <strong>zárolva van</strong>, és nem lehet törölni." +msgid "The field %field is locked and cannot be edited." +msgstr "%field mező zárolva van és nem szerkeszthető." +msgid "%type basic information" +msgstr "%type alapvető információ" +msgid "" +"Advanced usage only: PHP code that returns a default value. Should not " +"include <?php ?> delimiters. If this field is filled out, the " +"value returned by this code will override any value specified above. " +"Expected format: <pre>!sample</pre>To figure out the expected format, " +"you can use the <em>devel load</em> tab provided by <a " +"href=\"@link_devel\">devel module</a> on a %type content page." +msgstr "" +"Csak haladóknak: PHP kód, ami visszaadja az alapértelmezett " +"értéket. Nem szükséges <?php ?> elemek közé zárni. Ha ez " +"a mező ki van töltve, a kód által visszaadott érték felülír " +"minden fentebb megadott értéket. Az elvárt formátum: " +"<pre>!sample</pre>Az elvárt formátum megértéséhez használható a " +"<em>devel betöltés</em> fül, melyet a <a href=\"@link_devel\">devel " +"modul</a> szolgáltat az ilyen típusú oldalakon: %type." +msgid "Maximum number of values users can enter for this field." +msgstr "" +"A felhasználók által a mezőbe írható értékek maximális " +"száma." +msgid "" +"'Unlimited' will provide an 'Add more' button so the users can add as " +"many values as they like." +msgstr "" +"„Korlátlan” esetén a felhasználóknak megjelenik egy „Újabb " +"elem hozzáadása” nyomógomb, amellyel annyi értéket adhatnak " +"hozzá, amennyit csak akarnak." +msgid "The PHP code for 'default value' returned @value, which is invalid." +msgstr "" +"Az „alapértelmezett értéket” adó PHP kód ezt az értéket " +"adta vissza, ami érvénytelen: @value." +msgid "%name must be an integer." +msgstr "%name értékének egésznek kell lennie." +msgid "%name must be a positive integer." +msgstr "%name értékének pozitív egésznek kell lennie." +msgid "%name must be a number." +msgstr "%name értékének számnak kell lennie." +msgid "" +"You should make sure that the used field exists in the given content " +"type." +msgstr "" +"Meg kell győződni arról, hogy a használt mező létezik-e már az " +"adott tartalomtípusban." +msgid "Advanced: Specify the fields value with PHP code" +msgstr "Haladó: a mezők értékének beállítása PHP kóddal" +msgid "" +"Advanced usage only: PHP code that returns the value to set. Should " +"not include <?php ?> delimiters. If this field is filled out, " +"the value returned by this code will override any value specified " +"above. Expected format: <pre>!sample</pre>Using <a " +"href=\"@link_devel\">devel.module's</a> 'devel load' tab on a content " +"page might help you figure out the expected format." +msgstr "" +"Csak haladóknak: PHP kód, ami visszaadja a beállítandó értéket. " +"Nem szükséges <?php ?> elemek közé zárni. Ha ez a mező ki " +"van töltve, a kód által visszaadott érték felülír minden " +"fentebb megadott értéket. Az elvárt formátum: <pre>!sample</pre>Az " +"elvárt formátum megértéséhez használható a <em>devel " +"betöltés</em> fül, melyet a <a href=\"@link_devel\">devel modul</a> " +"szolgáltat a tartalom oldalakon." +msgid "You have to return the default value in the expected format." +msgstr "" +"Vissza kell adni az alapértelmezett értéket az elvárt " +"formátumban." +msgid "Populate @node's field '@field'" +msgstr "@node @field mezejének felhasználása" +msgid "Field has value" +msgstr "A mezőnek van értéke" +msgid "" +"You should make sure that the used field exists in the given content " +"type. The condition returns TRUE, if the selected field has the given " +"value." +msgstr "" +"Meg kell győződni arról, hogy a használt mező létezik az adott " +"tartalomtípusban. A feltétel igaz értéket ad vissza, ha a " +"kiválasztott mezőnek az értéke egyezik a megadott értékkel." +msgid "Field has changed" +msgstr "A mező megváltozott" +msgid "Content containing changes" +msgstr "A tartalom változásokat tartalmaz" +msgid "Content not containing changes" +msgstr "A tartalom nem tartalmaz változásokat" +msgid "@node's field '@field' has value" +msgstr "@node @field mezejének van értéke" +msgid "Select the machine-name of the field to look at." +msgstr "" +"A programok által kezelt név kiválasztása a mezőhöz, melyet " +"figyel." +msgid "@node's field '@field' has been changed" +msgstr "@node @field mezeje megváltozott" +msgid "Referenced node unfiltered title. WARNING - raw user input." +msgstr "" +"A hivatkozott tartalom szűretlen címe. Figyelem - nyers " +"felhasználói bevitel." +msgid "Formatted html link to the referenced node." +msgstr "Formázott html hivatkozás a hivatkozott tartalomhoz." +msgid "Relative path alias to the referenced node." +msgstr "Relatív útvonal álnév a hivatkozott tartalomhoz." +msgid "Absolute path alias to the referenced node." +msgstr "Teljes útvonal álnév a hivatkozott tartalomhoz." +msgid "Relative path alias to the referenced user." +msgstr "Relatív útvonal álnév a hivatkozott felhasználóhoz." +msgid "Absolute path alias to the referenced user." +msgstr "Teljes útvonal álnév a hivatkozott felhasználóhoz." +msgid "Field: @widget_label (@field_name) - @field_type" +msgstr "Mező: @widget_label (@field_name) - @field_type" +msgid "Field on the referenced node." +msgstr "Mező a hivatkozott tartalmon." +msgid "" +"Configure how the label is going to be displayed. This option takes no " +"effect when \"Override title\" option is enabled, the specified block " +"title is displayed instead." +msgstr "" +"A címke megjelenítési módjának beállítása. A beállítás " +"hatástalan, ha a „Cím felülírása” engedélyezett, helyette a " +"megadott blokk címe lesz megjelenítve." +msgid "Field formatter" +msgstr "Mező formázó" +msgid "Select a formatter." +msgstr "Formázó kiválasztása." +msgid "\"@s\" field: @widget_label (@field_name) - @field_type" +msgstr "„@s” mező: @widget_label (@field_name) - @field_type" +msgid "@label (!name)" +msgstr "@label (!name)" +msgid "@label (!name) - !column" +msgstr "@label (!name) - !column" +msgid "@label-truncated - !column" +msgstr "@label-truncated - !column" +msgid "Appears in: @types" +msgstr "Ez használja: @types" +msgid "<No value>" +msgstr "< Nincs érték >" +msgid "Widget label (@label)" +msgstr "Felületi elem cimke (@label)" +msgid "Custom label" +msgstr "Egyedi cimke" +msgid "(first item is 0)" +msgstr "(az első elem 0)" +msgid "(start from last values)" +msgstr "(kezdés az utolsó értéktől)" +msgid "" +"The delta allows you to select which item in a multiple value field to " +"key the relationship off of. Select \"1\" to use the first item, \"2\" " +"for the second item, and so on. If you select \"All\", each item in " +"the field will create a new row, which may appear to cause duplicates." +msgstr "" +"A delta lehetőséget ad annak kiválasztására, hogy a több " +"értékű mező melyik eleme legyen a kulcs a kapcsolatban. Az „1” " +"kiválasztása az első használja, a „2” a másodikat, és így " +"tovább. Ha a „Mind” van kiválasztva, akkor a mező minden eleme " +"új sort hoz létre, mely többszörös megjelenést okozhat." +msgid "" +"The delta allows you to select which item in a multiple value field " +"will be used for sorting. Select \"1\" to use the first item, \"2\" " +"for the second item, and so on. If you select \"All\", each item in " +"the field will create a new row, which may appear to cause duplicates." +msgstr "" +"A delta lehetőséget ad annak kiválasztására, hogy a több " +"értékű mező melyik eleme legyen a kulcs a kapcsolatban. Az „1” " +"kiválasztása az első használja, a „2” a másodikat, és így " +"tovább. Ha a „Mind” van kiválasztva, akkor a mező minden eleme " +"új sort hoz létre, mely többszörös megjelenést okozhat." +msgid "You need to provide a label." +msgstr "Meg kell adni egy címkét." +msgid "You need to provide a group name." +msgstr "Meg kell adni a csoport nevét." +msgid "" +"The group name %group_name is invalid. The name must include only " +"lowercase unaccentuated letters, numbers, and underscores." +msgstr "" +"%group_name csoportnév érvénytelen. A név csak ékezet nélküli " +"kisbetűket, számokat és aláhúzásjeleket tartalmazhat." +msgid "" +"The group name %group_name is too long. The name is limited to 32 " +"characters, including the 'group_' prefix." +msgstr "" +"%group_name csoportnév túl hosszú. A név csak 32 karakter hosszú " +"lehet, beleértve a „group_” előtagot is." +msgid "The group name %group_name already exists." +msgstr "%group_name nevű csoport már létezik." +msgid "Add new group:" +msgstr "Új csoport hozzáadása:" +msgid "Add new group: you need to provide a label." +msgstr "Új csoport hozzáadása: meg kell adni egy címkét." +msgid "Add new group: you need to provide a group name." +msgstr "Új csoport hozzáadása: meg kell adni a csoport nevét." +msgid "Standard group" +msgstr "Egyszerű csoport" +msgid "Create display groups for CCK fields." +msgstr "Csoportokat hoz létre a CCK mezők számára." +msgid "Field group: @group in @type" +msgstr "Mezőcsoport: @group @type típusban" +msgid "All fields from this field group on the referenced node." +msgstr "" +"A hivatkozott tartalom ezen mezőcsoportjában található összes " +"mező." +msgid "Field group label" +msgstr "Mezőcsoport címkéje" +msgid "" +"Configure how the field group label is going to be displayed. This " +"option takes no effect when \"Override title\" option is enabled, the " +"specified block title is displayed instead." +msgstr "" +"A mezőcsoport címke megjelenítési módjának beállítása. A " +"beállítás hatástalan, ha a „Cím felülírása” " +"engedélyezett, helyette a megadott blokk címe lesz látható." +msgid "Fieldset - Collapsible" +msgstr "Mezőcsoport - Összecsukható" +msgid "Fieldset - Collapsed" +msgstr "Mezőcsoport - Összecsukott" +msgid "Field group format" +msgstr "Mezőcsoport formátum" +msgid "This option allows you to configure the field group format." +msgstr "Lehetővé teszi a mezőcsoport formátumának beállítását." +msgid "\"@s\" field group: @group in @type" +msgstr "„@s” mezőcsoport: @group @type típusban" +msgid "" +"Note that if the field has multiple values, only the first content " +"node will be loaded." +msgstr "" +"Megjegyzés: Ha a mezőnek több értéke is lehet, akkor csak az " +"első tartalom fog betöltődni." +msgid "There are no nodereference fields defined." +msgstr "Nincsenek tartalomra hivatkozó mezők meghatározva." +msgid "" +"<p>Choose the \"Views module\" view that selects the nodes that can be " +"referenced.<br />Note:</p>" +msgstr "" +"<p>Meg kell adni azt a <em>Views</em> nézetet, amely kiválasztja " +"azokat a tartalmakat, melyekre hivatkozni lehet.<br />Megjegyzés:</p>" +msgid "" +"<ul><li>Only views that have fields will work for this " +"purpose.</li><li>This will discard the \"Content types\" settings " +"above. Use the view's \"filters\" section instead.</li><li>Use the " +"view's \"fields\" section to display additional informations about " +"candidate nodes on node creation/edition form.</li><li>Use the view's " +"\"sort criteria\" section to determine the order in which candidate " +"nodes will be displayed.</li></ul>" +msgstr "" +"<ul><li>Ebben az esetben csak azok a nézetek működnek, melyek " +"mezőkkel rendelkeznek.</li><li>Ez felülbírálja a fentebb megadott " +"„tartalomtípus” beállításokat. A nézet „szűrők” része " +"használható helyette.</li><li>A nézet „mezők” részének " +"használatával további információkat lehet megjeleníteni a " +"lehetséges tartalmakról a tartalom létrehozó/szerkesztő " +"űrlapon.</li><li>A nézet „rendezési szempont” részének " +"használatával befolyásolható a lehetséges tartalmak " +"megjelenítési sorrendje.</li></ul>" +msgid "" +"<p>The list of nodes that can be referenced can be based on a \"Views " +"module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" +"<p>A hivatkozható tartalmak listája egy <em>Views</em> nézeten " +"alapul, de a megfelelő nézet nem található. <br />Megjegyzés:</p>" +msgid "%name: invalid input." +msgstr "%name: érvénytelen bevitel." +msgid "%name: found no valid post with that title." +msgstr "%name: nincs érvényes tartalom ezzel a címmel." +msgid "Only numbers and decimals are allowed in %field." +msgstr "" +"%field mezőben csak számok és tizedeselválasztó van " +"engedélyezve." +msgid "Only numbers are allowed in %field." +msgstr "%field mező csak számokat tartalmazhat." +msgid "" +"Only numbers and the decimal character (%decimal) are allowed in " +"%field." +msgstr "" +"%field mezőben csak számok és tizedeselválasztó (%decimal) van " +"engedélyezve." +msgid "" +"Note that if the field has multiple values, only the first user will " +"be loaded." +msgstr "" +"Megjegyzés: Ha a mezőnek több értéke is lehet, akkor csak az " +"első felhasználó lesz betöltve." +msgid "There are no userreference fields defined." +msgstr "Nincsenek felhasználóhivatkozás mezők meghatározva." +msgid "Advanced - Users that can be referenced (View)" +msgstr "Haladó - Felhasználók, akikre hivatkozni lehet (Nézet)" +msgid "View used to select the users" +msgstr "A felhasználók kiválasztásához használt nézet" +msgid "" +"<p>Choose the \"Views module\" view that selects the users that can be " +"referenced.<br />Note:</p>" +msgstr "" +"<p>Meg kell adni azt a <em>Views</em> nézetet, amely kiválasztja " +"azokat a felhasználókat, melyekre hivatkozni lehet.<br " +"/>Megjegyzés:</p>" +msgid "" +"<ul><li>Only views that have fields will work for this " +"purpose.</li><li>This will discard the \"Referenceable Roles\" and " +"\"Referenceable Status\" settings above. Use the view's \"filters\" " +"section instead.</li><li>Use the view's \"fields\" section to display " +"additional informations about candidate users on user creation/edition " +"form.</li><li>Use the view's \"sort criteria\" section to determine " +"the order in which candidate users will be displayed.</li></ul>" +msgstr "" +"<ul><li>Ebben az esetben csak azok a nézetek működnek, melyek " +"mezőkkel rendelkeznek.</li><li>Ez felülbírálja a fentebb megadott " +"„hivatkozható csoportok” és „hivatkozható állapot” " +"beállításokat. A nézet „szűrők” része használható " +"helyette.</li><li>A nézet „mezők” részének használatával " +"további információkat lehet megjeleníteni a lehetséges " +"felhasználókról a felhasználók létrehozó/szerkesztő " +"űrlapon.</li><li>A nézet „rendezési szempont” részének " +"használatával befolyásolható a lehetséges felhasználók " +"megjelenítési sorrendje.</li></ul>" +msgid "" +"<p>The list of user that can be referenced can be based on a \"Views " +"module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" +"<p>A hivatkozható felhasználók listája egy <em>Views</em> nézeten " +"alapul, de a megfelelő nézet nem található. <br />Megjegyzés:</p>" +msgid "%name: invalid user." +msgstr "%name: érvénytelen felhasználó." +msgid "New field" +msgstr "Új mező" +msgid "Existing field" +msgstr "Létező mező" +msgid "New group" +msgstr "Új csoport" +msgid "" +"Add fields and groups to the content type, and arrange them on content " +"display and input forms." +msgstr "" +"Mezők és csoportok hozzáadása a tartalomtípushoz, valamint a " +"tartalom megjelenésének és szerkesztő űrlapjának elrendezése." +msgid "" +"You can add a field to a group by dragging it below and to the right " +"of the group." +msgstr "" +"A mezőt úgy lehet egy csoporthoz adni, hogy a csoport neve alá, " +"majd egy kicsit jobbra kell húzni." +msgid "" +"Note: Installing the <a href=\"!adv_help\">Advanced help</a> module " +"will let you access more and better help." +msgstr "" +"Megjegyzés: az <a href=\"%21adv_help\">Advanced help</a> modul " +"telepítésével több és jobb segítség érhető el." +msgid "" +"Use the 'Exclude' checkbox to exclude an item from the !content value " +"passed to the node template." +msgstr "" +"A „Kizárás” jelölőnégyzet használatával az elem kizárható " +"a tartalom sablonnak átadott !content értékből." +msgid "@label (!name) - delta" +msgstr "@label (!name) - delta" +msgid "@label-truncated - delta" +msgstr "@label-truncated - delta" +msgid "Delta - Appears in: @types" +msgstr "Delta - Megjelenik ebben: @types" +msgid "" +"This form will process a content type and one or more fields from that " +"type and export the settings. The export created by this process can " +"be copied and pasted as an import into the current or any other " +"database. The import will add the fields to an existing content type " +"or create a new content type that includes the selected fields." +msgstr "" +"Ez az űrlap egy tartalomtípust vagy a típus egy vagy több " +"mezőjét fogja feldolgozni, valamint a beállításokat exportálni. " +"A feldolgozás által létrehozott export másolható és importként " +"beilleszthető az aktuális, vagy bármilyen más adatbázisba. Az " +"import hozzáadja a mezőket egy létező tartalomtípushoz, vagy " +"létrehoz egy új tartalomtípust, ami tartalmazza a kiválasztott " +"mezőket." +msgid "Blocked users" +msgstr "Blokkolt felhasználók" +msgid "The 'referenceable_status' option for %field has been fixed." +msgstr "%field mező „referenceable_status” beállítása javítva lett." diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-panels-content_types.de.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-panels-content_types.de.po new file mode 100644 index 0000000000000000000000000000000000000000..ab5812bd19321c3078def0d993cc4f031b371935 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-panels-content_types.de.po @@ -0,0 +1,66 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:18+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: includes/panels/content_types/content_field.inc:14 +msgid "Content field" +msgstr "Inhaltsfeld" + +#: includes/panels/content_types/content_field.inc:37 +msgid "@type: (@field_type) @field" +msgstr "@type: (@field_type) @field" + +#: includes/panels/content_types/content_field.inc:44 +msgid "Field on the referenced node." +msgstr "Feld auf dem referenzierten Beitrag." + +#: includes/panels/content_types/content_field.inc:100 +msgid "Block title" +msgstr "Blocktitel" + +#: includes/panels/content_types/content_field.inc:103 +msgid "Hidden" +msgstr "Versteckt" + +#: includes/panels/content_types/content_field.inc:105 +msgid "Configure how the label is going to be displayed." +msgstr "Die Darstellung der Beschreibung konfigurieren." + +#: includes/panels/content_types/content_field.inc:128 +msgid "Formatter" +msgstr "Formatierer" + +#: includes/panels/content_types/content_field.inc:131 +msgid "Select a formatter." +msgstr "Einen Formatierer auswählen." + +#: includes/panels/content_types/content_field.inc:147 +msgid "\"@s\" field (@name)" +msgstr "„@s“ Feld (@name)" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-panels-content_types.pot b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-panels-content_types.pot new file mode 100644 index 0000000000000000000000000000000000000000..a0f260a36a77111dc81d47402b5dde81a14ec513 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-panels-content_types.pot @@ -0,0 +1,55 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (includes-panels-content_types) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from file: content_field.inc,v 1.1.2.4 2009/06/02 15:05:27 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: includes/panels/content_types/content_field.inc:14 +msgid "Content field" +msgstr "" + +#: includes/panels/content_types/content_field.inc:37 +msgid "@type: (@field_type) @field" +msgstr "" + +#: includes/panels/content_types/content_field.inc:44 +msgid "Field on the referenced node." +msgstr "" + +#: includes/panels/content_types/content_field.inc:100 +msgid "Block title" +msgstr "" + +#: includes/panels/content_types/content_field.inc:103 +msgid "Hidden" +msgstr "" + +#: includes/panels/content_types/content_field.inc:105 +msgid "Configure how the label is going to be displayed." +msgstr "" + +#: includes/panels/content_types/content_field.inc:128 +msgid "Formatter" +msgstr "" + +#: includes/panels/content_types/content_field.inc:131 +msgid "Select a formatter." +msgstr "" + +#: includes/panels/content_types/content_field.inc:147 +msgid "\"@s\" field (@name)" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.de.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.de.po new file mode 100644 index 0000000000000000000000000000000000000000..d11d2eafbb35d1bdbf92dd71ad9b43a8a0d2f3dd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.de.po @@ -0,0 +1,88 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2008-11-05 12:54+0100\n" +"PO-Revision-Date: 2008-11-05 13:23+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: includes/views/handlers/content_handler_field.inc:56 +msgid "None" +msgstr "Keines" + +#: includes/views/handlers/content_handler_field.inc:57 +msgid "Widget label (@label)" +msgstr "Steuerelement (@label)" + +#: includes/views/handlers/content_handler_field.inc:58 +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: includes/views/handlers/content_handler_field.inc:64 +msgid "Custom label" +msgstr "Benutzerdefinierte Bezeichnung" + +#: includes/views/handlers/content_handler_field.inc:80 +msgid "Format" +msgstr "Format" + +#: includes/views/handlers/content_handler_field_multiple.inc:56 +msgid "Group multiple values" +msgstr "Mehrfachwerte gruppieren" + +#: includes/views/handlers/content_handler_field_multiple.inc:59 +msgid "If unchecked, each item in the field will create a new row, which may appear to cause duplicates. This setting is not compatible with click-sorting in table displays." +msgstr "" + +#: includes/views/handlers/content_handler_field_multiple.inc:63 +msgid "Show @count value(s)" +msgstr "@count Werte anzeigen" + +#: includes/views/handlers/content_handler_field_multiple.inc:74 +msgid "starting from @count" +msgstr "Beginnt bei @count" + +#: includes/views/handlers/content_handler_field_multiple.inc:85 +msgid "Reversed (start from last values)" +msgstr "Umgedreht (Beginnt bei den letzten Werten)" + +#: includes/views/handlers/content_handler_relationship.inc:40 +#: includes/views/handlers/content_handler_sort.inc:41 +msgid "All" +msgstr "Alle" + +#: includes/views/handlers/content_handler_relationship.inc:48 +#: includes/views/handlers/content_handler_sort.inc:49 +msgid "Delta" +msgstr "Delta" + +#: includes/views/handlers/content_handler_relationship.inc:49 +msgid "The delta allows you to select which item in a multiple value field to key the relationship off of. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "" + +#: includes/views/handlers/content_handler_sort.inc:50 +msgid "The delta allows you to select which item in a multiple value field will be used for sorting. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.pot b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.pot new file mode 100644 index 0000000000000000000000000000000000000000..b4be87b49d2ebd4b0880e4b554f23e473ace2046 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.pot @@ -0,0 +1,79 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (includes-views-handlers) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content_handler_field.inc,v 1.1.2.15 2009/03/30 22:54:16 yched +# content_handler_field_multiple.inc,v 1.1.2.18 2009/05/07 15:06:36 yched +# content_handler_relationship.inc,v 1.1.2.3 2008/10/24 12:31:58 yched +# content_handler_sort.inc,v 1.1.2.6 2008/10/25 00:36:41 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: includes/views/handlers/content_handler_field.inc:59 +msgid "None" +msgstr "" + +#: includes/views/handlers/content_handler_field.inc:60 +msgid "Widget label (@label)" +msgstr "" + +#: includes/views/handlers/content_handler_field.inc:61 +msgid "Custom" +msgstr "" + +#: includes/views/handlers/content_handler_field.inc:67 +msgid "Custom label" +msgstr "" + +#: includes/views/handlers/content_handler_field.inc:83 +msgid "Format" +msgstr "" + +#: includes/views/handlers/content_handler_field_multiple.inc:63 +msgid "Group multiple values" +msgstr "" + +#: includes/views/handlers/content_handler_field_multiple.inc:66 +msgid "If unchecked, each item in the field will create a new row, which may appear to cause duplicates. This setting is not compatible with click-sorting in table displays." +msgstr "" + +#: includes/views/handlers/content_handler_field_multiple.inc:70 +msgid "Show @count value(s)" +msgstr "" + +#: includes/views/handlers/content_handler_field_multiple.inc:81 +msgid "starting from @count" +msgstr "" + +#: includes/views/handlers/content_handler_field_multiple.inc:92 +msgid "Reversed (start from last values)" +msgstr "" + +#: includes/views/handlers/content_handler_relationship.inc:40 includes/views/handlers/content_handler_sort.inc:41 +msgid "All" +msgstr "" + +#: includes/views/handlers/content_handler_relationship.inc:48 includes/views/handlers/content_handler_sort.inc:49 +msgid "Delta" +msgstr "" + +#: includes/views/handlers/content_handler_relationship.inc:49 +msgid "The delta allows you to select which item in a multiple value field to key the relationship off of. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "" + +#: includes/views/handlers/content_handler_sort.inc:50 +msgid "The delta allows you to select which item in a multiple value field will be used for sorting. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..71178a07d20610941015afba7b226bc245603613 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views-handlers.sv.po @@ -0,0 +1,82 @@ +# $Id$ +# +# Swedish translation of Drupal (includes_views_handlers) +# Generated from files: +# content_handler_field.inc,v 1.1.2.13 2009/03/06 15:29:34 karens +# content_handler_field_multiple.inc,v 1.1.2.15 2008/12/29 23:34:35 yched +# content_handler_relationship.inc,v 1.1.2.3 2008/10/24 12:31:58 yched +# content_handler_sort.inc,v 1.1.2.6 2008/10/25 00:36:41 yched +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Includes Views Handlers 6.x\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-04-20 21:28+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: includes/views/handlers/content_handler_field.inc:59 +msgid "None" +msgstr "Ingen" + +#: includes/views/handlers/content_handler_field.inc:60 +msgid "Widget label (@label)" +msgstr "Etikett för gränssnittskomponent (@label)" + +#: includes/views/handlers/content_handler_field.inc:61 +msgid "Custom" +msgstr "Anpassad" + +#: includes/views/handlers/content_handler_field.inc:67 +msgid "Custom label" +msgstr "Anpassad etikett" + +#: includes/views/handlers/content_handler_field.inc:83 +msgid "Format" +msgstr "Format" + +#: includes/views/handlers/content_handler_field_multiple.inc:58 +msgid "Group multiple values" +msgstr "Gruppera multipla värden" + +#: includes/views/handlers/content_handler_field_multiple.inc:61 +msgid "If unchecked, each item in the field will create a new row, which may appear to cause duplicates. This setting is not compatible with click-sorting in table displays." +msgstr "Om ikryssat kommer varje alternativ i fältet att skapa en ny rad, vilket kan orsaka dubletter. Denna inställning är inte kompatibel med klickvis sortering i tabellvisning." + +#: includes/views/handlers/content_handler_field_multiple.inc:65 +msgid "Show @count value(s)" +msgstr "Visa @count värde(n)" + +#: includes/views/handlers/content_handler_field_multiple.inc:76 +msgid "starting from @count" +msgstr "med början från @count" + +#: includes/views/handlers/content_handler_field_multiple.inc:87 +msgid "Reversed (start from last values)" +msgstr "Omvänd (börja från sista värdet)" + +#: includes/views/handlers/content_handler_relationship.inc:40 +#: includes/views/handlers/content_handler_sort.inc:41 +msgid "All" +msgstr "Alla" + +#: includes/views/handlers/content_handler_relationship.inc:48 +#: includes/views/handlers/content_handler_sort.inc:49 +msgid "Delta" +msgstr "Delta" + +#: includes/views/handlers/content_handler_relationship.inc:49 +msgid "The delta allows you to select which item in a multiple value field to key the relationship off of. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "Delta låter dig välja vilka alternativ i ett fält med flera värden som inte släktskapet stämmer in för. Välj \"1\" för att använda det första alternativet, \"2\" för det andra alternativet, och så vidare. Om du väljer \"Alla\", kommer varje alternativ i fältet att skapa en ny rad, vilket kan orsaka dubletter." + +#: includes/views/handlers/content_handler_sort.inc:50 +msgid "The delta allows you to select which item in a multiple value field will be used for sorting. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "Delta låter dig välja vilka alternativ i ett fält med flera värden som kommer att användas för sortering. Välj \"1\" för att använda det första alternativet, \"2\" för det andra alternativet, och så vidare. Om du väljer \"Alla\", kommer varje alternativ i fältet att skapa en ny rad, vilket kan orsaka dubletter." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.de.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.de.po new file mode 100644 index 0000000000000000000000000000000000000000..0aa4553bf638c32d39f1fa2eac39338e4384549f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.de.po @@ -0,0 +1,40 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (includes-views) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from file: content.views.inc,v 1.1.2.10 2008/10/17 14:29:34 yched +# +msgid "" +msgstr "" +"Project-Id-Version: German Translation of CCK\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-03-09 22:56+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" + +#: includes/views/content.views.inc:245;261 +msgid "@label (!name)" +msgstr "@label (!name)" + +#: includes/views/content.views.inc:249 +msgid "@label (!name) - !column" +msgstr "@label (!name) - !column" + +#: includes/views/content.views.inc:250 +msgid "@label-truncated - !column" +msgstr "@label-truncated - !column" + +#: includes/views/content.views.inc:257 +msgid "Appears in: @types" +msgstr "Erscheint in: @types" + +#: includes/views/content.views.inc:279 +msgid "<No value>" +msgstr "<kein Wert>" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.pot b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.pot new file mode 100644 index 0000000000000000000000000000000000000000..52c0e3441df3964ac838b3fbc398b3c8ebbeea17 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.pot @@ -0,0 +1,39 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (includes-views) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from file: content.views.inc,v 1.1.2.25 2009/04/11 14:50:53 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: includes/views/content.views.inc:252;268 +msgid "@label (!name)" +msgstr "" + +#: includes/views/content.views.inc:256 +msgid "@label (!name) - !column" +msgstr "" + +#: includes/views/content.views.inc:257 +msgid "@label-truncated - !column" +msgstr "" + +#: includes/views/content.views.inc:264 +msgid "Appears in: @types" +msgstr "" + +#: includes/views/content.views.inc:286 +msgid "<No value>" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..3194f331b9aec632b7dde1b6e4264a513d8de328 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes-views.sv.po @@ -0,0 +1,40 @@ +# $Id$ +# +# Swedish translation of Drupal (includes-views) +# Generated from file: content.views.inc,v 1.1.2.22 2009/01/14 13:19:47 karens +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Includes Views 6.x\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-04-20 21:13+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: includes/views/content.views.inc:245;261 +msgid "@label (!name)" +msgstr "@label (!name)" + +#: includes/views/content.views.inc:249 +msgid "@label (!name) - !column" +msgstr "@label (!name) - !column" + +#: includes/views/content.views.inc:250 +msgid "@label-truncated - !column" +msgstr "@label-truncated - !column" + +#: includes/views/content.views.inc:257 +msgid "Appears in: @types" +msgstr "Förekommer i: @types" + +#: includes/views/content.views.inc:279 +msgid "<No value>" +msgstr "<Inget värde>" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.de.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.de.po new file mode 100644 index 0000000000000000000000000000000000000000..6d572297b39d68d711dda2cb2594ab13c0da72c5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.de.po @@ -0,0 +1,583 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: 2009-06-16 19:15+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: includes/content.admin.inc:30 +msgid "edit" +msgstr "Bearbeiten" + +#: includes/content.admin.inc:33 +msgid "manage fields" +msgstr "Felder verwalten" + +#: includes/content.admin.inc:36 +msgid "delete" +msgstr "Löschen" + +#: includes/content.admin.inc:47 +msgid "No content types available." +msgstr "Keine Inhaltstypen vorhanden." + +#: includes/content.admin.inc:54 +msgid "» Add a new content type" +msgstr "» Neuen Inhaltstyp hinzufügen" + +#: includes/content.admin.inc:67;796;991 +msgid "Field name" +msgstr "Feldname" + +#: includes/content.admin.inc:67;811;997 +msgid "Field type" +msgstr "Feldtyp" + +#: includes/content.admin.inc:67 +msgid "Used in" +msgstr "Verwendet in" + +#: includes/content.admin.inc:71 +msgid "@field_name (Locked)" +msgstr "@field_name (Gesperrt)" + +#: includes/content.admin.inc:90 +msgid "No fields have been defined for any content type yet." +msgstr "Es wurden noch keine Felder für einen Inhaltstypen festgelegt." + +# not literally, English needs work +#: includes/content.admin.inc:106 +#, fuzzy +msgid "This content type has inactive fields. Inactive fields are not included in lists of available fields until their modules are enabled." +msgstr "Dieser Inhaltstyp enthält inaktive Felder. Inaktive Felder werden nicht in den Listen der verfügbaren Felder angezeigt, bis die Module aktiviert werden." + +#: includes/content.admin.inc:108 +msgid "!field (!field_name) is an inactive !field_type field that uses a !widget_type widget." +msgstr "!field (!field_name) ist ein inaktives !field_type-Feld, das ein !widget_type-Steuerelement verwendet." + +#: includes/content.admin.inc:170;196 +msgid "Configure" +msgstr "Konfigurieren" + +# Schreibgeschützt +#: includes/content.admin.inc:181 +msgid "Locked" +msgstr "Gesperrt" + +#: includes/content.admin.inc:237 +msgid "- Select a field type -" +msgstr "- Feldtyp auswählen -" + +#: includes/content.admin.inc:238 +msgid "- Select a widget -" +msgstr "- Steuerelement auswählen -" + +#: includes/content.admin.inc:253 +msgid "Field name (a-z, 0-9, _)" +msgstr "Feldname (a-z, 0-9, _)" + +#: includes/content.admin.inc:258 +msgid "Type of data to store." +msgstr "Der zu speichernde Datentyp." + +#: includes/content.admin.inc:263;295 +msgid "Form element to edit the data." +msgstr "Formularelement zum Bearbeiten der Daten." + +#: includes/content.admin.inc:279 +msgid "- Select an existing field -" +msgstr "- Vorhandenes Feld auswählen -" + +#: includes/content.admin.inc:290 +msgid "Field to share" +msgstr "Feld für gemeinsame Nutzung" + +#: includes/content.admin.inc:324 +msgid "Group name (a-z, 0-9, _)" +msgstr "Gruppenname (a-z, 0-9, _)" + +#: includes/content.admin.inc:373 +msgid "Add new field: you need to provide a label." +msgstr "Neues Feld hinzufügen: Eine Beschriftung muss angegeben werden." + +#: includes/content.admin.inc:378 +msgid "Add new field: you need to provide a field name." +msgstr "Neues Feld hinzufügen: Ein Feldname muss angegeben werden." + +#: includes/content.admin.inc:392 +msgid "Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Neues Feld hinzufügen: Der Feldname %field ist ungültig. Der Name darf nur nicht-akzentuierte Kleinbuchstaben, Zahlen und Unterstriche enthalten." + +#: includes/content.admin.inc:395 +msgid "Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix." +msgstr "Neues Feld hinzufügen: Der Feldname %field_name ist zu lang. Der Name ist inklusive dem Präfix ‚field_‘ auf 32 Zeichen begrenzt." + +#: includes/content.admin.inc:399 +msgid "Add new field: the name 'field_instance' is a reserved name." +msgstr "Neues Feld hinzufügen: Der Name ‚field_instance‘ ist ein reservierter Name." + +#: includes/content.admin.inc:411 +msgid "Add new field: the field name %field_name already exists." +msgstr "Neues Feld hinzufügen: Der Feldname %field_name ist bereits vorhanden." + +#: includes/content.admin.inc:417 +msgid "Add new field: you need to select a field type." +msgstr "Neues Feld hinzufügen: Ein Feldtyp muss ausgewählt werden." + +#: includes/content.admin.inc:422 +msgid "Add new field: you need to select a widget." +msgstr "Neues Feld hinzufügen: Ein Steuerelement muss ausgewählt werden." + +#: includes/content.admin.inc:428 +msgid "Add new field: invalid widget." +msgstr "Neues Feld hinzufügen: Ungültiges Steuerelement." + +#: includes/content.admin.inc:449 +msgid "Add existing field: you need to provide a label." +msgstr "Vorhandenes Feld hinzufügen: Eine Beschriftung muss angegeben werden." + +#: includes/content.admin.inc:454 +msgid "Add existing field: you need to select a field." +msgstr "Vorhandenes Feld hinzufügen: Ein Feld muss ausgewählt werden." + +#: includes/content.admin.inc:459 +msgid "Add existing field: you need to select a widget." +msgstr "Vorhandenes Feld hinzufügen: Ein Steuerelement muss ausgewählt werden." + +#: includes/content.admin.inc:465 +msgid "Add existing field: invalid widget." +msgstr "Vorhandenes Feld hinzufügen: Ungültiges Steuerelement." + +#: includes/content.admin.inc:514 +msgid "There was a problem creating field %label." +msgstr "Beim Erstellen des Feldes %label ist ein Fehler aufgetreten." + +#: includes/content.admin.inc:526 +msgid "The field %label cannot be added to a content type because it is locked." +msgstr "Das Feld %label ist gesperrt und kann deshalb zu keinem Inhaltstyp hinzugefügt werden." + +#: includes/content.admin.inc:536 +msgid "There was a problem adding field %label." +msgstr "Beim Hinzufügen des Feldes %label ist ein Fehler aufgetreten." + +#: includes/content.admin.inc:578 +msgid "There are no fields configured for this content type. You can add new fields on the <a href=\"@link\">Manage fields</a> page." +msgstr "Für diesen Inhaltstyp sind keine Felder konfiguriert. Neue Felder können auf der <a href=\"@link\">Felder verwalten</a>-Seite hinzugefügt werden." + +#: includes/content.admin.inc:625;668 +msgid "Include" +msgstr "Einschließen" + +#: includes/content.admin.inc:637 +msgid "no styling" +msgstr "kein Design" + +#: includes/content.admin.inc:638 +msgid "simple" +msgstr "einfach" + +#: includes/content.admin.inc:639 +msgid "fieldset" +msgstr "Feldgruppe" + +#: includes/content.admin.inc:640 +msgid "fieldset - collapsible" +msgstr "Feldgruppe - Zusammenklappbar" + +#: includes/content.admin.inc:641 +msgid "fieldset - collapsed" +msgstr "Feldgruppe - Zusammengeklappt" + +#: includes/content.admin.inc:697 +msgid "Your settings have been saved." +msgstr "Die Einstellungen wurden gespeichert." + +#: includes/content.admin.inc:767 +msgid "@type: @field (@label)" +msgstr "@type: @field (@label)" + +#: includes/content.admin.inc:793 +msgid "Edit basic information" +msgstr "Basisinformation bearbeiten" + +#: includes/content.admin.inc:799 +msgid "The machine-readable name of the field. This name cannot be changed." +msgstr "Der maschinenlesbare Name des Feldes. Der Name kann nicht geändert werden." + +#: includes/content.admin.inc:807 +msgid "A human-readable name to be used as the label for this field in the %type content type." +msgstr "Ein Name der im Inhaltstyp %type als Beschriftung für dieses Feld verwendet werden soll." + +#: includes/content.admin.inc:814 +msgid "The type of data you would like to store in the database with this field. This option cannot be changed." +msgstr "Der Datentyp der mit diesem Feld in der Datenbank gespeichert werden soll. Diese Option kann nicht geändert werden." + +#: includes/content.admin.inc:819;1003 +msgid "Widget type" +msgstr "Steuerelement" + +#: includes/content.admin.inc:823 +msgid "The type of form element you would like to present to the user when creating this field in the %type content type." +msgstr "Der Formularelementtyp der dem Benutzer angezeigt wird, wenn dieses Feld im Inhaltstyp %type erstellt wird." + +#: includes/content.admin.inc:833 +#: includes/content.rules.inc:66 +msgid "Continue" +msgstr "Fortfahren" + +#: includes/content.admin.inc:861 +msgid "Updated basic settings for field %label." +msgstr "Die Basiseinstellungen für das Feld %label wurden aktualisiert." + +#: includes/content.admin.inc:865 +msgid "There was a problem updating the basic settings for field %label." +msgstr "Beim Aktualsisieren der Basiseinstellungen des Feldes %label trat ein Problem auf." + +#: includes/content.admin.inc:892 +msgid "Are you sure you want to remove the field %field?" +msgstr "Soll das Feld %field wirklich gelöscht werden?" + +#: includes/content.admin.inc:894 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Falls sich Daten in diesem Feld befinden, gehen diese verloren. Diese Aktion kann nicht rückgängig gemacht werden." + +#: includes/content.admin.inc:901 +msgid "This field is <strong>locked</strong> and cannot be removed." +msgstr "Das Feld ist <strong>gesperrt</strong> und kann nicht entfernt werden." + +#: includes/content.admin.inc:922 +msgid "Removed field %field from %type." +msgstr "Das Feld %field von %type wurde gelöscht." + +#: includes/content.admin.inc:927 +msgid "There was a problem deleting %field from %type." +msgstr "Beim Löschen von %field in %type ist ein Fehler aufgetreten." + +#: includes/content.admin.inc:946 +msgid "The field %field is locked and cannot be edited." +msgstr "Das Feld %field ist gesperrt und kann nicht bearbeitet werden." + +#: includes/content.admin.inc:980 +msgid "%type basic information" +msgstr "Basisinformation für %type" + +#: includes/content.admin.inc:1010;1189 +msgid "Change basic information" +msgstr "Basisinformation ändern" + +#: includes/content.admin.inc:1016 +msgid "%type settings" +msgstr "Einstellungen für %type" + +#: includes/content.admin.inc:1017 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Diese Einstellungen gelten nur für das Feld %field, wie es im Inhaltstyp %type vorkommt." + +#: includes/content.admin.inc:1034 +msgid "Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags" +msgstr "Eine Hilfestellung, die dem Benutzer unter diesem Feld im Eingabeformular angezeigt wird.<br />Zulässige HTML-Tags: @tags" + +#: includes/content.admin.inc:1060 +msgid "Default value" +msgstr "Standardwert" + +#: includes/content.admin.inc:1090;1245 +#: includes/content.rules.inc:93 +msgid "'@column' => value for @column" +msgstr "'@column' => Wert für @column" + +#: includes/content.admin.inc:1092;1247 +#: includes/content.rules.inc:95 +msgid "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" +msgstr "" +"return array(\n" +" 0 => array(@columns),\n" +" // Normalerweise würde man hier aufhören. Soll der ‚Standardwert‘\n" +" // mehrwertig sein, können weitere Werte eingetragen werden:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" + +#: includes/content.admin.inc:1100 +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>To figure out the expected format, you can use the <em>devel load</em> tab provided by <a href=\"@link_devel\">devel module</a> on a %type content page." +msgstr "Nur erweiterte Verwendung: PHP-Code der einen Standardwert zurückliefert. Dieser sollte keine <?php ?> Trennzeichen enthalten. Sollte dieses Feld ausgefüllt werden, wird der von diesem Code zurückgegebene Wert jeden oberhalb angegebenen Wert übersteuern. Das erwartete Format lautet: <pre>!sample</pre>Um das erwartete Format herauszufinden, kann der vom <a href=\"@link_devel\">Devel-Modul</a> auf einer %type-Inhaltsseite zu Verfügung gestellte <em>Devel laden</em>-Reiter verwendet werden." + +#: includes/content.admin.inc:1111 +msgid "This PHP code was set by an administrator and will override any value specified above." +msgstr "Dieser PHP-Code wurde vom Administrator eingestellt und wird jeden oben angegeben Wert übersteuern." + +#: includes/content.admin.inc:1118 +msgid "Global settings" +msgstr "Globale Einstellungen" + +#: includes/content.admin.inc:1119 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Diese Einstellungen gelten für das Feld %field in jedem Inhaltstyp, indem das Feld erscheint." + +#: includes/content.admin.inc:1123 +msgid "Required" +msgstr "Erforderlich" + +#: includes/content.admin.inc:1126 +msgid "Maximum number of values users can enter for this field." +msgstr "Die maximale Anzahl an Werten, die Benutzer für dieses Feld eingeben können." + +#: includes/content.admin.inc:1128 +msgid "'Unlimited' will provide an 'Add more' button so the users can add as many values as they like." +msgstr "„Unbegrenzt“ stellt Benutzern einen „Weitere hinzufügen“-Schaltknopf zu Verfügung, damit diese so viele Werte hinzufügen können wie sie möchten." + +#: includes/content.admin.inc:1130 +msgid "Warning! Changing this setting after data has been created could result in the loss of data!" +msgstr "Warnung! Die Änderung dieser Einstellung kann nach Erstellung von Daten zu Datenverlust führen!" + +#: includes/content.admin.inc:1133 +msgid "Number of values" +msgstr "Anzahl von Werten" + +#: includes/content.admin.inc:1249 +msgid "The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value" +msgstr "Der Standardwert den PHP-Code bei ungültigen Werten zurückliefert.<br/>Erwartetes Format: <pre>!sample</pre>zurückgegebener Wert: @value" + +#: includes/content.admin.inc:1288 +msgid "The PHP code for 'default value' returned @value, which is invalid." +msgstr "Der PHP-Code für den „Standardwert“ lieferte den ungültigen Wert „@value“ zurück." + +#: includes/content.admin.inc:1292 +msgid "The default value is invalid." +msgstr "Der Standardwert ist ungültig." + +#: includes/content.admin.inc:1316 +msgid "Added field %label." +msgstr "Das Feld %label wurde hinzugefügt." + +#: includes/content.admin.inc:1320 +msgid "Saved field %label." +msgstr "Das Feld %label wurde gespeichert." + +#: includes/content.admin.inc:1678 +msgid "Processing" +msgstr "Verarbeitung läuft" + +#: includes/content.admin.inc:1679 +msgid "The update has encountered an error." +msgstr "Die Aktualisierung ist auf einen Fehler gestoßen." + +#: includes/content.admin.inc:1693 +msgid "The database has been altered and data has been migrated or deleted." +msgstr "Die Datenbank wurde geändert und die Daten wurden migriert oder gelöscht." + +#: includes/content.admin.inc:1696 +msgid "An error occurred and database alteration did not complete." +msgstr "Ein Fehler ist aufgetreten und die Datenbankänderung konnte nicht abgeschlossen werden." + +#: includes/content.admin.inc:1799 +msgid "Processing %title" +msgstr "%title wird verarbeitet" + +#: includes/content.admin.inc:1865 +msgid "%name must be an integer." +msgstr "%name muss eine Ganzzahl sein." + +#: includes/content.admin.inc:1875 +msgid "%name must be a positive integer." +msgstr "%name muss eine positive Ganzzahl sein." + +#: includes/content.admin.inc:1885 +msgid "%name must be a number." +msgstr "%name muss eine Zahl sein." + +#: includes/content.admin.inc:1697 +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "1 Eintrag wurde erfolgreich verarbeitet:" +msgstr[1] "@count Einträge wurden erfolgreich verarbeitet:" + +#: includes/content.crud.inc:589 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "Die Inhaltsfeldtabelle %old_name wurde in %new_name umbenannt und die Feldinstanzen wurden aktualisiert." + +#: includes/content.crud.inc:633 +msgid "The content fields table %name has been deleted." +msgstr "Die Inhaltsfeldtabelle %name wurde gelöscht." + +#: includes/content.node_form.inc:223 +msgid "Add another item" +msgstr "Weiteren Eintrag hinzufügen" + +#: includes/content.rules.inc:15 +msgid "Populate a field" +msgstr "Ein Feld füllen" + +#: includes/content.rules.inc:23;224 +msgid "You should make sure that the used field exists in the given content type." +msgstr "Das verwendete Feld sollte in dem angegebenen Inhaltstyp vorhanden sein." + +#: includes/content.rules.inc:56 +msgid "Select the machine-name of the field." +msgstr "Den maschinenlesbaren Namen des Feldes auswählen." + +#: includes/content.rules.inc:84 +msgid "Advanced: Specify the fields value with PHP code" +msgstr "Erweitert: Die Feldwerte mit PHP-Code festlegen" + +# not literally +#: includes/content.rules.inc:102 +msgid "Advanced usage only: PHP code that returns the value to set. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>Using <a href=\"@link_devel\">devel.module's</a> 'devel load' tab on a content page might help you figure out the expected format." +msgstr "Nur erweiterte Verwendung: PHP-Code der den einzustellenden Wert zurückliefert. Dieser sollte keine <?php ?> Trennzeichen enthalten. Sollte dieses Feld ausgefüllt werden, wird der von diesem Code zurückgegebene Wert jeden oberhalb angegebenen Wert übersteuern. Das erwartete Format lautet: <pre>!sample</pre>Um das erwartete Format herauszufinden, kann der vom <a href=\"@link_devel\">Devel-Modul</a> auf einer Inhaltsseite zu Verfügung gestellte <em>Devel laden</em>-Reiter möglicherweise helfen." + +#: includes/content.rules.inc:130 +msgid "You have to return the default value in the expected format." +msgstr "Der standardmäßige Wert muss im erwarteten Format zurückgegeben werden." + +#: includes/content.rules.inc:193 +msgid "Populate @node's field '@field'" +msgstr "Das Feld ‚@field‘ von @node füllen" + +#: includes/content.rules.inc:210 +msgid "Field has value" +msgstr "Das Feld enthält einen Wert" + +#: includes/content.rules.inc:215 +msgid "You should make sure that the used field exists in the given content type. The condition returns TRUE, if the selected field has the given value." +msgstr "Das verwendete Feld sollte in dem angegebenen Inhaltstyp vorhanden sein. Die Bedingung gibt TRUE zurück, wenn das ausgewählte Feld den Sollwert enthält." + +#: includes/content.rules.inc:219 +msgid "Field has changed" +msgstr "Feld wurde geändert" + +#: includes/content.rules.inc:221 +msgid "Content containing changes" +msgstr "Der Inhalt enthält Änderungen" + +#: includes/content.rules.inc:222 +msgid "Content not containing changes" +msgstr "Der Inhalt enthält keine Änderungen" + +#: includes/content.rules.inc:259 +msgid "@node's field '@field' has value" +msgstr "Das Feld ‚@field‘ von @node enthät einen Wert" + +# not literally +#: includes/content.rules.inc:279 +#, fuzzy +msgid "Select the machine-name of the field to look at." +msgstr "Den maschinenlesbaren Name des Feldes auswählen, indem nachgeschaut werden soll." + +# @node? +#: includes/content.rules.inc:285 +msgid "@node's field '@field' has been changed" +msgstr "Das Feld ‚@field‘ von @node wurde geändert" + +#: includes/content.token.inc:12;15 +msgid "Token" +msgstr "Token" + +#: includes/content.token.inc:81 +msgid "Referenced node ID" +msgstr "Referenzierte Beitrags-ID" + +#: includes/content.token.inc:82 +msgid "Referenced node title" +msgstr "Referenzierter Beitragstitel" + +#: includes/content.token.inc:83 +msgid "Referenced node unfiltered title. WARNING - raw user input." +msgstr "Ungefilterter referenzierter Beitragstitel. WARNUNG: Original Benutzereingabe." + +#: includes/content.token.inc:84 +msgid "Formatted html link to the referenced node." +msgstr "Formatierter HTML-Link zu dem referenzierten Beitrag." + +#: includes/content.token.inc:85 +msgid "Relative path alias to the referenced node." +msgstr "Relativer Pfadalias zu dem referenzierten Beitrag." + +#: includes/content.token.inc:86 +msgid "Absolute path alias to the referenced node." +msgstr "Absoluter Pfadalias zu dem referenzierten Beitrag." + +#: includes/content.token.inc:114 +msgid "Raw number value" +msgstr "Unbearbeiteter Zahlenwert" + +#: includes/content.token.inc:115 +msgid "Formatted number value" +msgstr "Formatierter Zahlenwert" + +#: includes/content.token.inc:138 +msgid "Raw, unfiltered text" +msgstr "Unbearbeiteter, ungefilterter Text" + +#: includes/content.token.inc:139 +msgid "Formatted and filtered text" +msgstr "Formatierter und gefilterter Text" + +#: includes/content.token.inc:161 +msgid "Referenced user ID" +msgstr "Referenzierte Benutzer-ID" + +#: includes/content.token.inc:162 +msgid "Referenced user name" +msgstr "Referenzierter Benutzername" + +#: includes/content.token.inc:163 +msgid "Formatted HTML link to referenced user" +msgstr "Formatierter HTML-Link zu dem referenzierten Benutzer." + +#: includes/content.token.inc:164 +msgid "Relative path alias to the referenced user." +msgstr "Relativer Pfadalias zu dem referenzierten Benutzer." + +#: includes/content.token.inc:165 +msgid "Absolute path alias to the referenced user." +msgstr "Absoluter Pfadalias zu dem referenzierten Benutzer." + +#~ msgid "Inline" +#~ msgstr "Inline" +#~ msgid "Content field" +#~ msgstr "Inhaltsfeld" +#~ msgid "A content field from the referenced node." +#~ msgstr "Ein Inhaltsfeld von dem referenzierten Beitrag." +#~ msgid "Block title" +#~ msgstr "Blocktitel" +#~ msgid "Hidden" +#~ msgstr "Versteckt" +#~ msgid "Configure how the label is going to be displayed." +#~ msgstr "Die Darstellung der Beschreibung konfigurieren." +#~ msgid "Field / Formatter" +#~ msgstr "Feld / Formatierer" +#~ msgid "Select a field and formatter." +#~ msgstr "Ein Feld und Formatierer auswählen." +#~ msgid "\"@s\" field @name" +#~ msgstr "„@s“ Feld @name" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..87380fa584d828d6040246f457c1348b0f737000 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.fr.po @@ -0,0 +1,420 @@ +# translation of SB-cck-6.x-2.x-dev.po to +# translation of cck-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-cck-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-03 07:41+0200\n" +"PO-Revision-Date: 2008-07-03 18:04+0100\n" +"Last-Translator: Damien Tournoud <damz@prealable.org>\n" +"Language-Team: <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: France\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: KBabel 1.11.4\n" + +#: includes/content.admin.inc:16;212 +msgid "Name" +msgstr "Nom" + +#: includes/content.admin.inc:16;212 +msgid "Type" +msgstr "Type" + +#: includes/content.admin.inc:16;212 +msgid "Operations" +msgstr "Opérations" + +#: includes/content.admin.inc:30 +msgid "edit" +msgstr "éditer" + +#: includes/content.admin.inc:33 +msgid "add field" +msgstr "ajouter un champ" + +#: includes/content.admin.inc:34 +msgid "manage fields" +msgstr "gérer les champs" + +#: includes/content.admin.inc:37 +msgid "delete" +msgstr "supprimer" + +#: includes/content.admin.inc:48 +msgid "No content types available." +msgstr "Aucun type de contenu disponible." + +#: includes/content.admin.inc:55 +msgid "» Add a new content type" +msgstr "» Ajouter un nouveau type de contenu" + +#: includes/content.admin.inc:64;602;856 +msgid "Field name" +msgstr "Nom du champ" + +#: includes/content.admin.inc:64;632;643;862 +msgid "Field type" +msgstr "Type de champ" + +#: includes/content.admin.inc:64 +msgid "Used in" +msgstr "Utilisé dans" + +#: includes/content.admin.inc:87 +msgid "No fields have been defined for any content type yet." +msgstr "Aucun champ n'est pour l'instant défini sur l'ensemble des types de contenu." + +#: includes/content.admin.inc:112;291 +msgid "There are no fields configured for this content type. You can !link." +msgstr "Il n'y a aucun champ configuré pour ce type de contenu. Vous pouvez néanmoins dès maintenant !link." + +#: includes/content.admin.inc:113;292 +msgid "Add a new field" +msgstr "ajouter un nouveau champ" + +#: includes/content.admin.inc:137 +msgid "To change the order of a field, grab a drag-and-drop handle under the Label column and drag the field to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the Save button at the bottom of the page." +msgstr "Pour changer l'ordre d'un champ, utilisez la poignée qui figure sous la colonne Étiquette et faites glisser le champ jusqu'à l'emplacement désiré. Pour manipuler la poignée (l'icône en forme de croix), cliquez sur l'icône et maintenez enfoncé le bouton de la souris. N'oubliez pas que vos modifications ne seront prises en compte que lorsque vous aurez cliqué sur le bouton <em>Enregistrer</em> qui figure en base de page." + +#: includes/content.admin.inc:147;163 +msgid "Configure" +msgstr "Configurer" + +#: includes/content.admin.inc:212 +msgid "Weight" +msgstr "Poids" + +#: includes/content.admin.inc:319;360 +msgid "Above" +msgstr "Au dessus" + +#: includes/content.admin.inc:320 +msgid "Inline" +msgstr "Sur la même ligne" + +#: includes/content.admin.inc:321;346;361;369 +msgid "<Hidden>" +msgstr "<Caché>" + +#: includes/content.admin.inc:364 +msgid "no styling" +msgstr "aucune mise en forme" + +#: includes/content.admin.inc:365 +msgid "simple" +msgstr "simple" + +#: includes/content.admin.inc:366 +msgid "fieldset" +msgstr "groupe de champs" + +#: includes/content.admin.inc:367 +msgid "fieldset - collapsible" +msgstr "groupe de champs - repliable" + +#: includes/content.admin.inc:368 +msgid "fieldset - collapsed" +msgstr "groupe de champs - replié" + +#: includes/content.admin.inc:413 +msgid "Field" +msgstr "Champ" + +#: includes/content.admin.inc:460 +msgid "Your settings have been saved." +msgstr "Vos paramètres ont été enregistrés." + +#: includes/content.admin.inc:477 +msgid "No field modules are enabled. You need to <a href=\"!modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "Aucun module de champs n'est activé. Vous devez en <a href=\"!modules_url\">activer un</a>, par exemple le module Text, avant de pouvoir ajouter des champs." + +#: includes/content.admin.inc:519 +msgid "Add existing field" +msgstr "Ajouter un champ existant" + +#: includes/content.admin.inc:547 +msgid "Added field %label." +msgstr "Le champ '%label' a été ajouté." + +#: includes/content.admin.inc:550 +msgid "There was a problem adding field %label." +msgstr "Un problème est survenu lors de l'ajout du champ '%label'." + +#: includes/content.admin.inc:590 +msgid "Create new field" +msgstr "Créer un nouveau champ" + +#: includes/content.admin.inc:597 +msgid "Edit basic information" +msgstr "Éditer les informations de base" + +#: includes/content.admin.inc:606 +msgid "The machine-readable name of the field." +msgstr "Nom du champ, lisible par une machine." + +#: includes/content.admin.inc:610 +msgid "This name cannot be changed." +msgstr " Ce nom ne peut être modifié." + +#: includes/content.admin.inc:618 +msgid "This name cannot be changed later! The name will be prefixed with 'field_' and can include lowercase unaccented letters, numbers, and underscores. The length of the name, including the prefix, is limited to no more than 32 letters." +msgstr " Ce nom ne pourra pas être modifié par la suite ! Le nom sera préfixé par 'field_' et peut inclure des lettres minuscules non accentués, des nombres et des caractères \"espace souligné\". La longueur du nom, y compris le préfixe, est limitée à un total de 32 caractères." + +#: includes/content.admin.inc:626 +msgid "A human-readable name to be used as the label for this field in the %type content type." +msgstr "Nom lisible par une personne, destiné à servir d'étiquette pour ce champ au sein du type de contenu '%type'." + +#: includes/content.admin.inc:636 +msgid "The type of data you would like to store in the database with this field." +msgstr "Type de données que vous souhaitez enregistrer, par le biais de ce champ, dans la base de données." + +#: includes/content.admin.inc:646 +msgid "The type of data you would like to store in the database with this field. This option cannot be changed." +msgstr "Type de données que vous souhaitez enregistrer, par le biais de ce champ, dans la base de données. Cette option ne peut être modifiée." + +#: includes/content.admin.inc:651;869 +msgid "Widget type" +msgstr "Type de widget" + +#: includes/content.admin.inc:655 +msgid "The type of form element you would like to present to the user when creating this field in the %type content type." +msgstr "Type d'élément de formulaire que vous souhaitez présenter à l'utilisateur lorsqu'il renseigne ce champ dans le type de contenu '%type'." + +#: includes/content.admin.inc:669 +msgid "Continue" +msgstr "Continuer" + +#: includes/content.admin.inc:692 +msgid "The field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Le nom de champ '%field_name' est invalide. Le nom ne doit comporter que des lettres minuscules non accentuées, des nombres ou des espaces soulignés." + +#: includes/content.admin.inc:695 +msgid "The field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix." +msgstr "Le nom de champ '%field_name' est trop long. La longueur du nom est limitée à 32 caractères, y compris le préfixe 'field_'." + +#: includes/content.admin.inc:706 +msgid "The field name %field_name already exists." +msgstr "Le nom de champ '%field_name' existe déjà." + +#: includes/content.admin.inc:709 +msgid "The name 'field_instance' is a reserved name." +msgstr "Le nom 'field_instance' est un nom réservé." + +#: includes/content.admin.inc:741 +msgid "Created field %label." +msgstr "Le champ '%label' a été créé." + +#: includes/content.admin.inc:745 +msgid "There was a problem creating field %label." +msgstr "Un problème est survenu à la création du champ '%label'." + +#: includes/content.admin.inc:754 +msgid "Update field %label." +msgstr "Mettre à jour le champ '%label'." + +#: includes/content.admin.inc:758 +msgid "There was a problem updating field %label." +msgstr "Un problème est survenu à la mise à jour du champ '%label'." + +#: includes/content.admin.inc:786 +msgid "Are you sure you want to remove the field %field?" +msgstr "Êtes-vous certain de vouloir enlever le champ '%field' ?" + +#: includes/content.admin.inc:789 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Si vous avez encore du contenu dans ce champ, il sera perdu. Cette action est irréversible." + +#: includes/content.admin.inc:808 +msgid "Removed field %field from %type." +msgstr "Le champ '%field' de '%type' a été enlevé." + +#: includes/content.admin.inc:813 +msgid "There was a problem deleting %field from %type." +msgstr "Un problème est survenu à la suppression du champ '%field' du type '%type'." + +#: includes/content.admin.inc:846 +msgid "%type basic information" +msgstr "Informations de base pour '%type'" + +#: includes/content.admin.inc:876 +msgid "Change basic information" +msgstr "Modifier les informations de base" + +#: includes/content.admin.inc:882 +msgid "%type settings" +msgstr "Paramètres de '%type'" + +#: includes/content.admin.inc:883 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Ces paramètres ne s'applique qu'au champ '%field' tel qu'il apparaît dans le type contenu '%type'." + +#: includes/content.admin.inc:900 +msgid "Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags" +msgstr "Instructions à présenter à l'utilisateur sous ce champ, dans le formulaire d'édition.<br />Balises HTML autorisées : @tags" + +#: includes/content.admin.inc:908 +msgid "Default value" +msgstr "Valeur par défaut" + +#: includes/content.admin.inc:955 +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>Using !link_devel's 'devel load' tab on a %type content page might help you figure out the expected format." +msgstr "Réservé à une utilisation avancée : code PHP renvoyant la valeur par défaut du champ. Ne doit pas inclure les délimiteurs <?php ?>. Si ce champ est renseigné, la valeur renvoyée par le code supplante toute valeur indiquée ci-desus. Format attendu : <pre>!sample</pre> Vous pouvez utiliser l'onglet 'devel load' du module !link_devel sur un nœud de type '%type' pour mieux comprendre le format attendu." + +#: includes/content.admin.inc:966 +msgid "This PHP code was set by an administrator and will override any value specified above." +msgstr "Ce code PHP a été inséré par un administrateur et supplantera toute valeur spécifiée ci-dessus." + +#: includes/content.admin.inc:973 +msgid "Global settings" +msgstr "Paramètres globaux" + +#: includes/content.admin.inc:974 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Ces paramètres s'appliquent au champ '%field' dans tous les types de contenu où il apparaît." + +#: includes/content.admin.inc:978 +msgid "Required" +msgstr "Obligatoire" + +#: includes/content.admin.inc:983 +msgid "Number of values" +msgstr "Nombre de valeurs" + +#: includes/content.admin.inc:984 +msgid "Unlimited" +msgstr "Illimité" + +#: includes/content.admin.inc:986 +msgid "Select a specific number of values for this field, or 'Unlimited' to provide an 'Add more' button so the users can add as many values as they like." +msgstr "Choisissez un nombre de valeurs pour ce champ, ou 'Illimité' pour proposer un bouton 'Ajouter' aux utilisateurs, de sorte qu'ils peuvent insérer autant de valeurs qu'ils le souhaitent." + +#: includes/content.admin.inc:986 +msgid "Warning! Changing this setting after data has been created could result in the loss of data!" +msgstr "Attention ! Changer ce paramètre alors que des données ont déjà été créées peut conduire à perdre des données !" + +#: includes/content.admin.inc:1001 +msgid "Save field settings" +msgstr "Enregistrer les paramètres du champ" + +#: includes/content.admin.inc:1094 +msgid "The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value" +msgstr "Le code PHP de valeur par défaut a renvoyé une valeur incorrecte.<br/>Format attendu : <pre>!sample</pre> Valeur renvoyée : @value" + +#: includes/content.admin.inc:1131 +msgid "The default value PHP code created @value which is invalid." +msgstr "Le code PHP de valeur par défaut a créé @value, qui est invalide." + +#: includes/content.admin.inc:1135 +msgid "The default value is invalid." +msgstr "La valeur par défaut est invalide." + +#: includes/content.admin.inc:1158 +msgid "Saved field %label." +msgstr "Champ '%label' enregistré." + +#: includes/content.admin.inc:1463 +msgid "Processing" +msgstr "Exécution" + +#: includes/content.admin.inc:1464 +msgid "The update has encountered an error." +msgstr "La mise à jour a échoué." + +#: includes/content.admin.inc:1478 +msgid "The database has been altered and data has been migrated or deleted." +msgstr "La base de données a été modifiée et des données ont été déplacées ou supprimées." + +#: includes/content.admin.inc:1481 +msgid "An error occurred and database alteration did not complete." +msgstr "Une erreur est survenue et a interrompu la modification de la base de données." + +#: includes/content.admin.inc:1584 +msgid "Processing %title" +msgstr "'%title' en cours de traitement" + +#: includes/content.admin.inc:1482 +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "1 élément traité avec succès :" +msgstr[1] "@count éléments traités avec succès :" + +#: includes/content.crud.inc:591 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "La table de champs a été renommée de '%old_name' à '%new_name' et les instances des champs ont été mises à jour." + +#: includes/content.crud.inc:629 +msgid "The content fields table %name has been deleted." +msgstr "La table de champs '%name' a été supprimée." + +#: includes/content.node_form.inc:206 +msgid "Add another item" +msgstr "Ajouter un autre élément" + +#: includes/content.token.inc:60 +msgid "Referenced node ID" +msgstr "Identifiant du nœud référencé" + +#: includes/content.token.inc:61 +msgid "Referenced node title" +msgstr "Titre du nœud référencé" + +#: includes/content.token.inc:62 +msgid "Formatted HTML link to the node" +msgstr "Lien HTML mis en forme vers le nœud" + +#: includes/content.token.inc:86 +msgid "Raw number value" +msgstr "Valeur numérique brute" + +#: includes/content.token.inc:87 +msgid "Formatted number value" +msgstr "Valeur numérique mise en forme" + +#: includes/content.token.inc:110 +msgid "Raw, unfiltered text" +msgstr "Texte brut, non filtré" + +#: includes/content.token.inc:111 +msgid "Formatted and filtered text" +msgstr "Texte filtré et mis en forme" + +#: includes/content.token.inc:133 +msgid "Referenced user ID" +msgstr "Identifiant de l'utilisateur référencé" + +#: includes/content.token.inc:134 +msgid "Referenced user name" +msgstr "Nom de l'utilisateur référencé" + +#: includes/content.token.inc:135 +msgid "Formatted HTML link to referenced user" +msgstr "Lien HTML mis en forme vers l'utilisateur référencé" + +#: includes/content.views.inc:93 +msgid "Appears in: @types" +msgstr "Apparaît dans : @types" + +#: includes/content.views.inc:291 +msgid "Format" +msgstr "Format" + +#: includes/content.views.inc:372 +msgid "Group multiple values" +msgstr "Grouper plusieurs valeurs" + +#: includes/content.views.inc:378 +msgid "Show @count value(s)" +msgstr "Afficher @count valeur(s)" + +#: includes/content.views.inc:387 +msgid "starting from @count" +msgstr "en commençant à @count" + +#: includes/content.views.inc:396 +msgid "Reversed (start from last values)" +msgstr "Inversé (commencer à partir des dernières valeurs)" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.pot b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.pot new file mode 100644 index 0000000000000000000000000000000000000000..9bb5e12ab08017a077737c166035bb91f67ff1a2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.pot @@ -0,0 +1,534 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (includes) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content.admin.inc,v 1.181.2.68 2009/06/02 14:49:07 yched +# content.rules.inc,v 1.1.2.6 2009/04/30 09:56:07 fago +# content.crud.inc,v 1.76.2.14 2008/11/07 15:02:02 yched +# content.node_form.inc,v 1.7.2.19 2009/06/02 20:18:27 yched +# content.token.inc,v 1.5.2.8 2008/12/05 14:59:22 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: includes/content.admin.inc:30 +msgid "edit" +msgstr "" + +#: includes/content.admin.inc:33 +msgid "manage fields" +msgstr "" + +#: includes/content.admin.inc:36 +msgid "delete" +msgstr "" + +#: includes/content.admin.inc:47 +msgid "No content types available." +msgstr "" + +#: includes/content.admin.inc:54 +msgid "» Add a new content type" +msgstr "" + +#: includes/content.admin.inc:67;796;991 +msgid "Field name" +msgstr "" + +#: includes/content.admin.inc:67;811;997 +msgid "Field type" +msgstr "" + +#: includes/content.admin.inc:67 +msgid "Used in" +msgstr "" + +#: includes/content.admin.inc:71 +msgid "@field_name (Locked)" +msgstr "" + +#: includes/content.admin.inc:90 +msgid "No fields have been defined for any content type yet." +msgstr "" + +#: includes/content.admin.inc:106 +msgid "This content type has inactive fields. Inactive fields are not included in lists of available fields until their modules are enabled." +msgstr "" + +#: includes/content.admin.inc:108 +msgid "!field (!field_name) is an inactive !field_type field that uses a !widget_type widget." +msgstr "" + +#: includes/content.admin.inc:170;196 +msgid "Configure" +msgstr "" + +#: includes/content.admin.inc:181 +msgid "Locked" +msgstr "" + +#: includes/content.admin.inc:237 +msgid "- Select a field type -" +msgstr "" + +#: includes/content.admin.inc:238 +msgid "- Select a widget -" +msgstr "" + +#: includes/content.admin.inc:253 +msgid "Field name (a-z, 0-9, _)" +msgstr "" + +#: includes/content.admin.inc:258 +msgid "Type of data to store." +msgstr "" + +#: includes/content.admin.inc:263;295 +msgid "Form element to edit the data." +msgstr "" + +#: includes/content.admin.inc:279 +msgid "- Select an existing field -" +msgstr "" + +#: includes/content.admin.inc:290 +msgid "Field to share" +msgstr "" + +#: includes/content.admin.inc:324 +msgid "Group name (a-z, 0-9, _)" +msgstr "" + +#: includes/content.admin.inc:373 +msgid "Add new field: you need to provide a label." +msgstr "" + +#: includes/content.admin.inc:378 +msgid "Add new field: you need to provide a field name." +msgstr "" + +#: includes/content.admin.inc:392 +msgid "Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "" + +#: includes/content.admin.inc:395 +msgid "Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix." +msgstr "" + +#: includes/content.admin.inc:399 +msgid "Add new field: the name 'field_instance' is a reserved name." +msgstr "" + +#: includes/content.admin.inc:411 +msgid "Add new field: the field name %field_name already exists." +msgstr "" + +#: includes/content.admin.inc:417 +msgid "Add new field: you need to select a field type." +msgstr "" + +#: includes/content.admin.inc:422 +msgid "Add new field: you need to select a widget." +msgstr "" + +#: includes/content.admin.inc:428 +msgid "Add new field: invalid widget." +msgstr "" + +#: includes/content.admin.inc:449 +msgid "Add existing field: you need to provide a label." +msgstr "" + +#: includes/content.admin.inc:454 +msgid "Add existing field: you need to select a field." +msgstr "" + +#: includes/content.admin.inc:459 +msgid "Add existing field: you need to select a widget." +msgstr "" + +#: includes/content.admin.inc:465 +msgid "Add existing field: invalid widget." +msgstr "" + +#: includes/content.admin.inc:514 +msgid "There was a problem creating field %label." +msgstr "" + +#: includes/content.admin.inc:526 +msgid "The field %label cannot be added to a content type because it is locked." +msgstr "" + +#: includes/content.admin.inc:536 +msgid "There was a problem adding field %label." +msgstr "" + +#: includes/content.admin.inc:578 +msgid "There are no fields configured for this content type. You can add new fields on the <a href=\"@link\">Manage fields</a> page." +msgstr "" + +#: includes/content.admin.inc:625;668 +msgid "Include" +msgstr "" + +#: includes/content.admin.inc:637 +msgid "no styling" +msgstr "" + +#: includes/content.admin.inc:638 +msgid "simple" +msgstr "" + +#: includes/content.admin.inc:639 +msgid "fieldset" +msgstr "" + +#: includes/content.admin.inc:640 +msgid "fieldset - collapsible" +msgstr "" + +#: includes/content.admin.inc:641 +msgid "fieldset - collapsed" +msgstr "" + +#: includes/content.admin.inc:697 +msgid "Your settings have been saved." +msgstr "" + +#: includes/content.admin.inc:767 +msgid "@type: @field (@label)" +msgstr "" + +#: includes/content.admin.inc:793 +msgid "Edit basic information" +msgstr "" + +#: includes/content.admin.inc:799 +msgid "The machine-readable name of the field. This name cannot be changed." +msgstr "" + +#: includes/content.admin.inc:807 +msgid "A human-readable name to be used as the label for this field in the %type content type." +msgstr "" + +#: includes/content.admin.inc:814 +msgid "The type of data you would like to store in the database with this field. This option cannot be changed." +msgstr "" + +#: includes/content.admin.inc:819;1003 +msgid "Widget type" +msgstr "" + +#: includes/content.admin.inc:823 +msgid "The type of form element you would like to present to the user when creating this field in the %type content type." +msgstr "" + +#: includes/content.admin.inc:833 includes/content.rules.inc:66 +msgid "Continue" +msgstr "" + +#: includes/content.admin.inc:861 +msgid "Updated basic settings for field %label." +msgstr "" + +#: includes/content.admin.inc:865 +msgid "There was a problem updating the basic settings for field %label." +msgstr "" + +#: includes/content.admin.inc:892 +msgid "Are you sure you want to remove the field %field?" +msgstr "" + +#: includes/content.admin.inc:894 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "" + +#: includes/content.admin.inc:901 +msgid "This field is <strong>locked</strong> and cannot be removed." +msgstr "" + +#: includes/content.admin.inc:922 +msgid "Removed field %field from %type." +msgstr "" + +#: includes/content.admin.inc:927 +msgid "There was a problem deleting %field from %type." +msgstr "" + +#: includes/content.admin.inc:946 +msgid "The field %field is locked and cannot be edited." +msgstr "" + +#: includes/content.admin.inc:980 +msgid "%type basic information" +msgstr "" + +#: includes/content.admin.inc:1010;1189 +msgid "Change basic information" +msgstr "" + +#: includes/content.admin.inc:1016 +msgid "%type settings" +msgstr "" + +#: includes/content.admin.inc:1017 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "" + +#: includes/content.admin.inc:1034 +msgid "Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags" +msgstr "" + +#: includes/content.admin.inc:1060 +msgid "Default value" +msgstr "" + +#: includes/content.admin.inc:1090;1245 includes/content.rules.inc:93 +msgid "'@column' => value for @column" +msgstr "" + +#: includes/content.admin.inc:1092;1247 includes/content.rules.inc:95 +msgid "return array(\n 0 => array(@columns),\n // You'll usually want to stop here. Provide more values\n // if you want your 'default value' to be multi-valued:\n 1 => array(@columns),\n 2 => ...\n);" +msgstr "" + +#: includes/content.admin.inc:1100 +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>To figure out the expected format, you can use the <em>devel load</em> tab provided by <a href=\"@link_devel\">devel module</a> on a %type content page." +msgstr "" + +#: includes/content.admin.inc:1111 +msgid "This PHP code was set by an administrator and will override any value specified above." +msgstr "" + +#: includes/content.admin.inc:1118 +msgid "Global settings" +msgstr "" + +#: includes/content.admin.inc:1119 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "" + +#: includes/content.admin.inc:1123 +msgid "Required" +msgstr "" + +#: includes/content.admin.inc:1126 +msgid "Maximum number of values users can enter for this field." +msgstr "" + +#: includes/content.admin.inc:1128 +msgid "'Unlimited' will provide an 'Add more' button so the users can add as many values as they like." +msgstr "" + +#: includes/content.admin.inc:1130 +msgid "Warning! Changing this setting after data has been created could result in the loss of data!" +msgstr "" + +#: includes/content.admin.inc:1133 +msgid "Number of values" +msgstr "" + +#: includes/content.admin.inc:1249 +msgid "The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value" +msgstr "" + +#: includes/content.admin.inc:1288 +msgid "The PHP code for 'default value' returned @value, which is invalid." +msgstr "" + +#: includes/content.admin.inc:1292 +msgid "The default value is invalid." +msgstr "" + +#: includes/content.admin.inc:1316 +msgid "Added field %label." +msgstr "" + +#: includes/content.admin.inc:1320 +msgid "Saved field %label." +msgstr "" + +#: includes/content.admin.inc:1678 +msgid "Processing" +msgstr "" + +#: includes/content.admin.inc:1679 +msgid "The update has encountered an error." +msgstr "" + +#: includes/content.admin.inc:1693 +msgid "The database has been altered and data has been migrated or deleted." +msgstr "" + +#: includes/content.admin.inc:1696 +msgid "An error occurred and database alteration did not complete." +msgstr "" + +#: includes/content.admin.inc:1799 +msgid "Processing %title" +msgstr "" + +#: includes/content.admin.inc:1865 +msgid "%name must be an integer." +msgstr "" + +#: includes/content.admin.inc:1875 +msgid "%name must be a positive integer." +msgstr "" + +#: includes/content.admin.inc:1885 +msgid "%name must be a number." +msgstr "" + +#: includes/content.admin.inc:1697 +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "" +msgstr[1] "" + +#: includes/content.crud.inc:589 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "" + +#: includes/content.crud.inc:633 +msgid "The content fields table %name has been deleted." +msgstr "" + +#: includes/content.node_form.inc:223 +msgid "Add another item" +msgstr "" + +#: includes/content.rules.inc:15 +msgid "Populate a field" +msgstr "" + +#: includes/content.rules.inc:23;224 +msgid "You should make sure that the used field exists in the given content type." +msgstr "" + +#: includes/content.rules.inc:56 +msgid "Select the machine-name of the field." +msgstr "" + +#: includes/content.rules.inc:84 +msgid "Advanced: Specify the fields value with PHP code" +msgstr "" + +#: includes/content.rules.inc:102 +msgid "Advanced usage only: PHP code that returns the value to set. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>Using <a href=\"@link_devel\">devel.module's</a> 'devel load' tab on a content page might help you figure out the expected format." +msgstr "" + +#: includes/content.rules.inc:130 +msgid "You have to return the default value in the expected format." +msgstr "" + +#: includes/content.rules.inc:193 +msgid "Populate @node's field '@field'" +msgstr "" + +#: includes/content.rules.inc:210 +msgid "Field has value" +msgstr "" + +#: includes/content.rules.inc:215 +msgid "You should make sure that the used field exists in the given content type. The condition returns TRUE, if the selected field has the given value." +msgstr "" + +#: includes/content.rules.inc:219 +msgid "Field has changed" +msgstr "" + +#: includes/content.rules.inc:221 +msgid "Content containing changes" +msgstr "" + +#: includes/content.rules.inc:222 +msgid "Content not containing changes" +msgstr "" + +#: includes/content.rules.inc:259 +msgid "@node's field '@field' has value" +msgstr "" + +#: includes/content.rules.inc:279 +msgid "Select the machine-name of the field to look at." +msgstr "" + +#: includes/content.rules.inc:285 +msgid "@node's field '@field' has been changed" +msgstr "" + +#: includes/content.token.inc:12;15 +msgid "Token" +msgstr "" + +#: includes/content.token.inc:81 +msgid "Referenced node ID" +msgstr "" + +#: includes/content.token.inc:82 +msgid "Referenced node title" +msgstr "" + +#: includes/content.token.inc:83 +msgid "Referenced node unfiltered title. WARNING - raw user input." +msgstr "" + +#: includes/content.token.inc:84 +msgid "Formatted html link to the referenced node." +msgstr "" + +#: includes/content.token.inc:85 +msgid "Relative path alias to the referenced node." +msgstr "" + +#: includes/content.token.inc:86 +msgid "Absolute path alias to the referenced node." +msgstr "" + +#: includes/content.token.inc:114 +msgid "Raw number value" +msgstr "" + +#: includes/content.token.inc:115 +msgid "Formatted number value" +msgstr "" + +#: includes/content.token.inc:138 +msgid "Raw, unfiltered text" +msgstr "" + +#: includes/content.token.inc:139 +msgid "Formatted and filtered text" +msgstr "" + +#: includes/content.token.inc:161 +msgid "Referenced user ID" +msgstr "" + +#: includes/content.token.inc:162 +msgid "Referenced user name" +msgstr "" + +#: includes/content.token.inc:163 +msgid "Formatted HTML link to referenced user" +msgstr "" + +#: includes/content.token.inc:164 +msgid "Relative path alias to the referenced user." +msgstr "" + +#: includes/content.token.inc:165 +msgid "Absolute path alias to the referenced user." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..31eede5683083ab1e9692b20b3f508e467cb54bb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/includes.sv.po @@ -0,0 +1,590 @@ +# $Id$ +# +# Swedish translation of Drupal (includes) +# Generated from files: +# content.admin.inc,v 1.181.2.64 2009/03/01 13:48:44 yched +# content.panels.inc,v 1.1.2.6 2008/11/03 14:12:41 yched +# content.rules.inc,v 1.1.2.4 2008/10/24 11:11:48 fago +# content.crud.inc,v 1.76.2.14 2008/11/07 15:02:02 yched +# content.node_form.inc,v 1.7.2.18 2009/02/10 22:53:04 yched +# content.token.inc,v 1.5.2.8 2008/12/05 14:59:22 yched +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Includes 6.x\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-04-20 22:52+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: includes/content.admin.inc:30 +msgid "edit" +msgstr "redigera" + +#: includes/content.admin.inc:33 +msgid "manage fields" +msgstr "hantera fält" + +#: includes/content.admin.inc:36 +msgid "delete" +msgstr "radera" + +#: includes/content.admin.inc:47 +msgid "No content types available." +msgstr "Inga innehållstyper tillgängliga." + +#: includes/content.admin.inc:54 +msgid "» Add a new content type" +msgstr "» Lägg till en ny innehållstyp" + +#: includes/content.admin.inc:67;789;984 +msgid "Field name" +msgstr "Fältnamn" + +#: includes/content.admin.inc:67;804;990 +msgid "Field type" +msgstr "Fälttyp" + +#: includes/content.admin.inc:67 +msgid "Used in" +msgstr "Används i" + +#: includes/content.admin.inc:71 +msgid "@field_name (Locked)" +msgstr "@field_name (Låst)" + +#: includes/content.admin.inc:90 +msgid "No fields have been defined for any content type yet." +msgstr "Inga fält har definierat för någon innehållstyp ännu." + +#: includes/content.admin.inc:106 +msgid "This content type has inactive fields. Inactive fields are not included in lists of available fields until their modules are enabled." +msgstr "Denna innehållstyp har inaktiva fält. Inaktiva fält inkluderas ej i listan av tillgängliga fält förrän deras moduler aktiverats." + +#: includes/content.admin.inc:108 +msgid "!field (!field_name) is an inactive !field_type field that uses a !widget_type widget." +msgstr "!field (!field_name) är ett inaktivt !field_type fält som använder en !widget_type gränssnittskomponent." + +#: includes/content.admin.inc:170;196 +msgid "Configure" +msgstr "Konfigurera" + +#: includes/content.admin.inc:181 +msgid "Locked" +msgstr "Låst" + +#: includes/content.admin.inc:237 +msgid "- Select a field type -" +msgstr "- Välj en fälttyp -" + +#: includes/content.admin.inc:238 +msgid "- Select a widget -" +msgstr "- Välj en gränssnittskomponent -" + +#: includes/content.admin.inc:253 +msgid "Field name (a-z, 0-9, _)" +msgstr "Fältnamn (a-z, 0-9, _)" + +#: includes/content.admin.inc:258 +msgid "Type of data to store." +msgstr "Typ av data att lagra." + +#: includes/content.admin.inc:263;295 +msgid "Form element to edit the data." +msgstr "Formulärbeståndsdel för att redigera datan." + +#: includes/content.admin.inc:279 +msgid "- Select an existing field -" +msgstr "- Välj ett befintligt fält -" + +#: includes/content.admin.inc:290 +msgid "Field to share" +msgstr "Fält att dela" + +#: includes/content.admin.inc:324 +msgid "Group name (a-z, 0-9, _)" +msgstr "Gruppnamn (a-z, 0-9, _)" + +#: includes/content.admin.inc:365 +msgid "Add new field: you need to provide a label." +msgstr "Lägg till nytt fält: du måste ange en etikett." + +#: includes/content.admin.inc:370 +msgid "Add new field: you need to provide a field name." +msgstr "Lägg till nytt fält: du måste ange ett fältnamn." + +#: includes/content.admin.inc:384 +msgid "Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Lägg till nytt fält: fältnamnet %field_name är ogiltigt. Namnet kan bara innehålla gemena tecken som inte är accentuerade, nummer och understreck." + +#: includes/content.admin.inc:387 +msgid "Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix." +msgstr "Lägg till nytt fält: fältnamnet %field_name är för långt. Namnet är begränsat till 32 tecken, inkluderat prefixet 'field_'." + +#: includes/content.admin.inc:391 +msgid "Add new field: the name 'field_instance' is a reserved name." +msgstr "Lägg till nytt fält: namnet 'field_instance' är ett reserverat namn." + +#: includes/content.admin.inc:403 +msgid "Add new field: the field name %field_name already exists." +msgstr "Lägg till nytt fält: fältnamnet %field_name existerar redan." + +#: includes/content.admin.inc:409 +msgid "Add new field: you need to select a field type." +msgstr "Lägg till nytt fält: du måste välja en fälttyp." + +#: includes/content.admin.inc:414 +msgid "Add new field: you need to select a widget." +msgstr "Lägg till nytt fält: du måste välja en gränssnittskomponent." + +#: includes/content.admin.inc:420 +msgid "Add new field: invalid widget." +msgstr "Lägg till nytt fält: ogiltig gränssnittskomponent." + +#: includes/content.admin.inc:441 +msgid "Add existing field: you need to provide a label." +msgstr "Lägg till existerande fält: du måste ange en etikett." + +#: includes/content.admin.inc:446 +msgid "Add existing field: you need to select a field." +msgstr "Lägg till existerande fält: du måste välja ett fält." + +#: includes/content.admin.inc:451 +msgid "Add existing field: you need to select a widget." +msgstr "Lägg till existerande fält: du måste välja en gränssnittskomponent." + +#: includes/content.admin.inc:457 +msgid "Add existing field: invalid widget." +msgstr "Lägg till existerande fält: ogiltig gränssnittskomponent." + +#: includes/content.admin.inc:506 +msgid "There was a problem creating field %label." +msgstr "Det uppstod ett problem med att skapa fältet %label." + +#: includes/content.admin.inc:518 +msgid "The field %label cannot be added to a content type because it is locked." +msgstr "Fältet %label kan inte läggas till en innehållstyp därför att det är låst." + +#: includes/content.admin.inc:528 +msgid "There was a problem adding field %label." +msgstr "Det uppstod ett problem med att lägga till fältet %label." + +#: includes/content.admin.inc:571 +msgid "There are no fields configured for this content type. You can add new fields on the <a href=\"@link\">Manage fields</a> page." +msgstr "Det finns inga fält konfigurerade för denna innehållstyp. Du kan lägga till nya fält på sidan <a href=\"@link\">Hantera fält</a>." + +#: includes/content.admin.inc:579 +#: includes/content.panels.inc:54 +msgid "Inline" +msgstr "Löpande" + +#: includes/content.admin.inc:618;661 +msgid "Include" +msgstr "Inkludera" + +#: includes/content.admin.inc:630 +msgid "no styling" +msgstr "ingen stil" + +#: includes/content.admin.inc:631 +msgid "simple" +msgstr "enkel" + +#: includes/content.admin.inc:632 +msgid "fieldset" +msgstr "fältgrupp" + +#: includes/content.admin.inc:633 +msgid "fieldset - collapsible" +msgstr "fältgrupp - hopfällbar" + +#: includes/content.admin.inc:634 +msgid "fieldset - collapsed" +msgstr "fältgrupp - hopfälld" + +#: includes/content.admin.inc:690 +msgid "Your settings have been saved." +msgstr "Dina inställningar har sparats." + +#: includes/content.admin.inc:760 +msgid "@type: @field (@label)" +msgstr "@type: @field (@label)" + +#: includes/content.admin.inc:786 +msgid "Edit basic information" +msgstr "Redigera grundläggande information." + +#: includes/content.admin.inc:792 +msgid "The machine-readable name of the field. This name cannot be changed." +msgstr "Det maskinläsbara namnet på fältet. Detta namn kan inte ändras." + +#: includes/content.admin.inc:800 +msgid "A human-readable name to be used as the label for this field in the %type content type." +msgstr "Det synliga namnet som skall användas som etikett för detta fält i innehållstypen %type." + +#: includes/content.admin.inc:807 +msgid "The type of data you would like to store in the database with this field. This option cannot be changed." +msgstr "Den typ av data som du vill lagra i databasen med detta fält. Detta val kan inte ändras." + +#: includes/content.admin.inc:812;996 +msgid "Widget type" +msgstr "Typ av gränssnittskomponent" + +#: includes/content.admin.inc:816 +msgid "The type of form element you would like to present to the user when creating this field in the %type content type." +msgstr "Typ av formulärbeståndsdel som du vill presentera för användaren när detta fält skapas i innehållstypen %type." + +#: includes/content.admin.inc:826 +#: includes/content.rules.inc:66 +msgid "Continue" +msgstr "Fortsätt" + +#: includes/content.admin.inc:854 +msgid "Updated basic settings for field %label." +msgstr "Uppdaterade grundläggande inställningar för fältet %label." + +#: includes/content.admin.inc:858 +msgid "There was a problem updating the basic settings for field %label." +msgstr "Det uppstod ett problem vid uppdateringen av de grundläggande inställningarna för fältet %label." + +#: includes/content.admin.inc:885 +msgid "Are you sure you want to remove the field %field?" +msgstr "Är du säker på att du vill ta bort fältet %field?" + +#: includes/content.admin.inc:887 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Om du har något innehåll kvar i detta fält kommer det att förloras. Denna åtgärd kan ångras." + +#: includes/content.admin.inc:894 +msgid "This field is <strong>locked</strong> and cannot be removed." +msgstr "Det här fältet är <strong>låst</strong> och kan inte tas bort." + +#: includes/content.admin.inc:915 +msgid "Removed field %field from %type." +msgstr "Tog bort fältet %field från %type." + +#: includes/content.admin.inc:920 +msgid "There was a problem deleting %field from %type." +msgstr "Det uppstod ett problem vid borttagningen av %field från %type." + +#: includes/content.admin.inc:939 +msgid "The field %field is locked and cannot be edited." +msgstr "Fältet %field är låst och kan inte redigeras." + +#: includes/content.admin.inc:973 +msgid "%type basic information" +msgstr "Grundläggande information för %type" + +#: includes/content.admin.inc:1003;1182 +msgid "Change basic information" +msgstr "Ändra grundläggande information" + +#: includes/content.admin.inc:1009 +msgid "%type settings" +msgstr "Inställningar för %type" + +#: includes/content.admin.inc:1010 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Dessa inställningar gäller enbart för fältet %field så som det visas i innehållstypen %type." + +#: includes/content.admin.inc:1027 +msgid "Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags" +msgstr "Instruktioner att visa för användaren nedanför detta fält för redigeringsformuläret.<br />Tillåtna HTML-taggar: @tags" + +#: includes/content.admin.inc:1053 +msgid "Default value" +msgstr "Förvalt värde" + +#: includes/content.admin.inc:1083;1238 +#: includes/content.rules.inc:93 +msgid "'@column' => value for @column" +msgstr "'@column' => värde för @column" + +#: includes/content.admin.inc:1085;1240 +#: includes/content.rules.inc:95 +msgid "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" +msgstr "" +"return array(\n" +" 0 => array(@columns),\n" +" // Vanligtvis vill du avsluta här. Tillhandahåll fler värden\n" +" // om du vill att ditt 'förvalda värde' skall innehålla flera värden:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" + +#: includes/content.admin.inc:1093 +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>To figure out the expected format, you can use the <em>devel load</em> tab provided by <a href=\"@link_devel\">devel module</a> on a %type content page." +msgstr "Enbart avancerat användande: PHP-kod som returnerar ett förvalt värde. Skall inte inkludera avgränsarna <?php ?>. Om detta fält är ifyllt, kommer värdet som returneras av denna kod att åsidosätta värden specificerade ovan. Förväntat format: <pre>!sample</pre>För att komma underfund med det förväntade formatet kan du använda fliken <em>devel load</em> tillhandahållen av <a href=\"@link_devel\">modulen Devel</a> på en innehållssida av typen %type." + +#: includes/content.admin.inc:1104 +msgid "This PHP code was set by an administrator and will override any value specified above." +msgstr "Denna PHP-kod angavs av en administratör och kommer att åsidosätta värden specificerade ovan." + +#: includes/content.admin.inc:1111 +msgid "Global settings" +msgstr "Globala inställningar" + +#: includes/content.admin.inc:1112 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Dessa inställningar gäller för fältet %field på varje innehållstyp som det förekommer i." + +#: includes/content.admin.inc:1116 +msgid "Required" +msgstr "Krävd" + +#: includes/content.admin.inc:1119 +msgid "Maximum number of values users can enter for this field." +msgstr "Maximalt antal av värden som användare kan ange för detta fält." + +#: includes/content.admin.inc:1121 +msgid "'Unlimited' will provide an 'Add more' button so the users can add as many values as they like." +msgstr "\"Obegränsad\" kommer att tillhandahålla en knapp \"Lägg till fler\" så att användaren kan lägga till så många värden de vill." + +#: includes/content.admin.inc:1123 +msgid "Warning! Changing this setting after data has been created could result in the loss of data!" +msgstr "Varning! Ändras denna inställning efter att data har skapats kan resultera i förlust av data!" + +#: includes/content.admin.inc:1126 +msgid "Number of values" +msgstr "Antal värden" + +#: includes/content.admin.inc:1242 +msgid "The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value" +msgstr "PHP-kodens förvalda värde returnerade ett otillåtet värde.<br />Förväntat format: <pre>!sample</pre> Returnerat värde: @value" + +#: includes/content.admin.inc:1281 +msgid "The PHP code for 'default value' returned @value, which is invalid." +msgstr "PHP-kod för \"förvalt värde\" returnerade @value, som inte är giltigt." + +#: includes/content.admin.inc:1285 +msgid "The default value is invalid." +msgstr "Det förvalta värdet är inte giltigt." + +#: includes/content.admin.inc:1309 +msgid "Added field %label." +msgstr "Lade till fält %label." + +#: includes/content.admin.inc:1313 +msgid "Saved field %label." +msgstr "Sparade fält %label." + +#: includes/content.admin.inc:1662 +msgid "Processing" +msgstr "Bearbetar" + +#: includes/content.admin.inc:1663 +msgid "The update has encountered an error." +msgstr "Uppdateringen stötte på ett fel." + +#: includes/content.admin.inc:1677 +msgid "The database has been altered and data has been migrated or deleted." +msgstr "Databasen har ändrats och data har flyttats eller raderats." + +#: includes/content.admin.inc:1680 +msgid "An error occurred and database alteration did not complete." +msgstr "Ett fel inträffade och ändringen av databasen slutfördes inte." + +#: includes/content.admin.inc:1783 +msgid "Processing %title" +msgstr "Bearbetar %title" + +#: includes/content.admin.inc:1849 +msgid "%name must be an integer." +msgstr "%name måste vara ett heltal." + +#: includes/content.admin.inc:1859 +msgid "%name must be a positive integer." +msgstr "%name måste vara ett positivt heltal." + +#: includes/content.admin.inc:1869 +msgid "%name must be a number." +msgstr "%name måste vara ett nummer." + +#: includes/content.admin.inc:1681 +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "1 alternativ bearbetades utan problem:" +msgstr[1] "@count alternativ bearbetades utan problem:" + +#: includes/content.crud.inc:589 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "Tabellen för innehållets fält %old_name har döpts om till %new_name och förekomsten av fälten har uppdaterats." + +#: includes/content.crud.inc:633 +msgid "The content fields table %name has been deleted." +msgstr "Tabellen för innehållets fält %name har raderats." + +#: includes/content.node_form.inc:223 +msgid "Add another item" +msgstr "Lägg till ytterligare alternativ" + +#: includes/content.panels.inc:21;35 +msgid "Content field" +msgstr "Fält för innehåll" + +#: includes/content.panels.inc:38 +msgid "A content field from the referenced node." +msgstr "Ett fält för innehåll från den refererande noden." + +#: includes/content.panels.inc:52 +msgid "Block title" +msgstr "Titel på block" + +#: includes/content.panels.inc:55 +msgid "Hidden" +msgstr "Gömd" + +#: includes/content.panels.inc:57 +msgid "Configure how the label is going to be displayed." +msgstr "Konfigurera hur etiketten skall visas." + +#: includes/content.panels.inc:73 +msgid "Field / Formatter" +msgstr "Fält / Formaterare" + +#: includes/content.panels.inc:76 +msgid "Select a field and formatter." +msgstr "Välj ett fält och formaterare" + +#: includes/content.panels.inc:92 +msgid "\"@s\" field @name" +msgstr "fältet \"@s\" för @name" + +#: includes/content.rules.inc:15 +msgid "Populate a field" +msgstr "Befolka ett fält" + +#: includes/content.rules.inc:23;212 +msgid "You should make sure that the used field exists in the given content type." +msgstr "Du måste säkerställa att det använda fältet existerar i den givna innehållstypen." + +#: includes/content.rules.inc:56 +msgid "Select the machine-name of the field." +msgstr "Vält maskinnamnet för fältet." + +#: includes/content.rules.inc:84 +msgid "Advanced: Specify the fields value with PHP code" +msgstr "Avancerat: Specificera fältets värde med PHP-kod" + +#: includes/content.rules.inc:102 +msgid "Advanced usage only: PHP code that returns the value to set. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>Using <a href=\"@link_devel\">devel.module's</a> 'devel load' tab on a content page might help you figure out the expected format." +msgstr "Enbart avancerat användande: PHP-kod som returnerar värdet som skall anges. Skall inte inkludera avgränsarna <?php ?>. Om detta fält är ifyllt, kommer värdet som returneras av denna kod att åsidosätta värden specificerade ovan. Förväntat format: <pre>!sample</pre>För att komma underfund med det förväntade formatet kan du använda fliken <em>devel load</em> tillhandahållen av <a href=\"@link_devel\">modulen Devel</a>." + +#: includes/content.rules.inc:130 +msgid "You have to return the default value in the expected format." +msgstr "Du måste returnera det förvalda värdet i det förväntade formatet." + +#: includes/content.rules.inc:181 +msgid "Populate @node's field '@field'" +msgstr "Befolka fältet \"@field\" för @node" + +#: includes/content.rules.inc:198 +msgid "Field has value" +msgstr "Fält har värde" + +#: includes/content.rules.inc:203 +msgid "You should make sure that the used field exists in the given content type. The condition returns TRUE, if the selected field has the given value." +msgstr "Du måste säkerställa att det använda fältet existerar i den givna innehållstypen. Villkoret returnerar SANT, om det valda fältet har det givna värdet." + +#: includes/content.rules.inc:207 +msgid "Field has changed" +msgstr "Fält har ändrats" + +#: includes/content.rules.inc:209 +msgid "Content containing changes" +msgstr "Innehåll innehåller ändringar" + +#: includes/content.rules.inc:210 +msgid "Content not containing changes" +msgstr "Innehåll innehåller inte ändringar" + +#: includes/content.rules.inc:249 +msgid "@node's field '@field' has value" +msgstr "Fältet \"@field\" för @node har värde" + +#: includes/content.rules.inc:269 +msgid "Select the machine-name of the field to look at." +msgstr "Välj maskinnamnet för fältet att titta på." + +#: includes/content.rules.inc:275 +msgid "@node's field '@field' has been changed" +msgstr "Fältet \"@field\" för @node har ändrats" + +#: includes/content.token.inc:12;15 +msgid "Token" +msgstr "Tecken" + +#: includes/content.token.inc:81 +msgid "Referenced node ID" +msgstr "ID för hänvisad nod" + +#: includes/content.token.inc:82 +msgid "Referenced node title" +msgstr "Titel för hänvisad nod" + +#: includes/content.token.inc:83 +msgid "Referenced node unfiltered title. WARNING - raw user input." +msgstr "Ofiltrerad titel för hänvisad nod. VARNING - obearbetad användarinmatning." + +#: includes/content.token.inc:84 +msgid "Formatted html link to the referenced node." +msgstr "Formatterad HTML-länk till den hänvisade noden." + +#: includes/content.token.inc:85 +msgid "Relative path alias to the referenced node." +msgstr "Relativ sökvägsalias till den hänvisade noden." + +#: includes/content.token.inc:86 +msgid "Absolute path alias to the referenced node." +msgstr "Absolut sökvägsalias till den hänvisade noden." + +#: includes/content.token.inc:114 +msgid "Raw number value" +msgstr "Obearbetat numervärde" + +#: includes/content.token.inc:115 +msgid "Formatted number value" +msgstr "Formaterat nummervärde" + +#: includes/content.token.inc:138 +msgid "Raw, unfiltered text" +msgstr "Obearbetat, ofiltrerad text" + +#: includes/content.token.inc:139 +msgid "Formatted and filtered text" +msgstr "Formatterad och filtrerad text" + +#: includes/content.token.inc:161 +msgid "Referenced user ID" +msgstr "ID för hänvisad användare" + +#: includes/content.token.inc:162 +msgid "Referenced user name" +msgstr "Namn för hänvisad användare" + +#: includes/content.token.inc:163 +msgid "Formatted HTML link to referenced user" +msgstr "Formatterad HTML-klnk till hänvisad användare" + +#: includes/content.token.inc:164 +msgid "Relative path alias to the referenced user." +msgstr "Relativt sökvägsalias till den hänvisade användaren." + +#: includes/content.token.inc:165 +msgid "Absolute path alias to the referenced user." +msgstr "Absolut sökvägsalias till den hänvisade användaren." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/it.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/it.po new file mode 100644 index 0000000000000000000000000000000000000000..395415d05907ba338668efd43935f3efede14e4c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/it.po @@ -0,0 +1,846 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# field.php,v 1.7.2.8 2007/03/01 00:20:35 yched +# text.module,v 1.41.2.12 2007/03/12 00:50:34 yched +# number.module,v 1.34.2.20 2007/03/01 04:51:54 yched +# content_admin.inc,v 1.28.2.35 2007/04/09 14:12:47 yched +# fieldgroup.module,v 1.1.4.31 2007/03/27 12:27:42 fago +# content_copy.module,v 1.1.2.7 2007/03/11 23:39:49 yched +# content.module,v 1.90.2.39 2007/03/11 23:39:49 yched +# content_crud.inc,v 1.4.2.11 2007/01/26 12:34:56 karens +# content_views.inc,v 1.2.2.14 2007/04/09 14:12:47 yched +# nodereference.module,v 1.39.2.17 2007/03/05 21:58:47 yched +# userreference.module,v 1.30.2.16 2007/03/05 21:58:47 yched +# optionwidgets.module,v 1.10.2.8 2007/03/29 12:52:13 yched +# optionwidgets.install,v 1.1.4.5 2007/01/25 17:23:26 yched +# content.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# content_copy.info,v 1.1.2.4 2007/01/08 13:29:21 karens +# fieldgroup.info,v 1.1.2.2 2007/01/05 11:57:46 yched +# nodereference.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# number.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# optionwidgets.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# text.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# userreference.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# +msgid "" +"" +msgstr "Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2007-07-08 16:34+0200\n" +"PO-Revision-Date: 2007-07-09 16:36+0100\n" +"Last-Translator: Alberto G. <alby115@tiscali.it>\n" +"Language-Team: Italian <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: field.php:106 +#: text.module:34 +msgid "Maximum length" +msgstr "Lunghezza massima" + +#: field.php:109 +#: text.module:37 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "Numero massimo di caratteri del campo. Lascialo vuoto per mantenerlo illimitato." + +#: field.php:217 +#: number.module:144 +#: text.module:118 +msgid "Illegal value for %name." +msgstr "Parametro %name non corretto." + +#: field.php:352 +#: text.module:213 +msgid "Rows" +msgstr "Righe" + +#: field.php:360 +#: text.module:221 +msgid "\"Rows\" must be a positive integer." +msgstr "\"Righe\" deve essere un intero positivo." + +#: content_admin.inc:15 +msgid "Field name" +msgstr "Nome del campo" + +#: content_admin.inc:15 +msgid "Field type" +msgstr "Tipo di campo" + +#: content_admin.inc:15 +msgid "Used in" +msgstr "Usato in" + +#: content_admin.inc:68 +msgid "There are no groups configured for this content type." +msgstr "Non ci sono gruppi impostati per questo tipo di contenuto." + +#: content_admin.inc:78 +msgid "There are no fields configured for this content type." +msgstr "Non ci sono campi impostati per questo tipo di contenuto." + +#: content_admin.inc:103 +msgid "group" +msgstr "gruppo" + +#: content_admin.inc:106 +msgid "configure" +msgstr "configura" + +#: content_admin.inc:107 +msgid "remove" +msgstr "rimuovi" + +#: content_admin.inc:158 +msgid "body" +msgstr "corpo" + +#: content_admin.inc:179 +msgid "Update" +msgstr "Aggiorna" + +#: content_admin.inc:203 +#: fieldgroup.module:84 +msgid "Label" +msgstr "Etichetta" + +#: content_admin.inc:203 +msgid "Name" +msgstr "Nome" + +#: content_admin.inc:203 +msgid "Type" +msgstr "Tipo" + +#: content_admin.inc:203 +msgid "Weight" +msgstr "Peso" + +#: content_admin.inc:203 +#: fieldgroup.module:512 +msgid "Group" +msgstr "Gruppo" + +#: content_admin.inc:203 +msgid "Operations" +msgstr "Operazioni" + +#: content_admin.inc:271 +msgid "No fields have been added to this group." +msgstr "Nessun campo è stato aggiunto a questo gruppo." + +#: content_admin.inc:276 +msgid "!label (!name)" +msgstr "!label (!nome)" + +#: content_admin.inc:311 +msgid "Updated field groups." +msgstr "Il campo dei gruppi è stato aggiornato." + +#: content_admin.inc:322 +msgid "Updated group weights." +msgstr "I pesi del gruppo sono stati aggiornati." + +#: content_admin.inc:333 +msgid "Updated field weights." +msgstr "I pesi del campo sono stati aggiornati." + +#: content_admin.inc:362 +#: content_copy.module:158 +#: fieldgroup.module:335 +msgid "Submit" +msgstr "Inoltra" + +#: content_admin.inc:367 +msgid "Field" +msgstr "Campo" + +#: content_admin.inc:402 +msgid "Your settings have been saved." +msgstr "Le tue impostazioni sono state salvate." + +#: content_admin.inc:412 +#: fieldgroup.module:479 +msgid "<Hidden>" +msgstr "<Nascosto>" + +#: content_admin.inc:415 +#: fieldgroup.module:478 +msgid "Above" +msgstr "Sopra" + +#: content_admin.inc:416 +msgid "Inline" +msgstr "Inlinea" + +#: content_admin.inc:442 +msgid "Teaser" +msgstr "Anteprima" + +#: content_admin.inc:443 +msgid "Full" +msgstr "Pieno" + +#: content_admin.inc:474 +msgid "Add existing field" +msgstr "Aggiungi un campo esistente" + +#: content_admin.inc:483 +#: content.module:108 +msgid "Add field" +msgstr "Aggiungi campo" + +#: content_admin.inc:509 +msgid "Create new field" +msgstr "Crea un nuovo campo" + +#: content_admin.inc:515 +msgid "The machine-readable name of the field.<br/>Allowed characters : unaccentuated a-z, numbers and _. All other characters will be discarded.<br/>You'll be able to choose a human-readable label for the field on next page" +msgstr "Il nome del campo leggibile dal calcolatore.<br/>Caratteri ammessi : a-z senza accenti, numeri e _. Tutti gli altri caratteri verranno scartati.<br/>Potrai scegliere una etichetta leggibile dall'utente nella prossima pagina." + +#: content_admin.inc:528 +msgid "Create field" +msgstr "Crea campo" + +#: content_admin.inc:540 +msgid "No field modules are enabled. You need to <a href=\"!modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "Non ci sono moduli di campo abilitati. Devi <a href=\"!modules_url\">abilitarne uno</a>, come il text.module, prima di poter aggiungere nuovi campi." + +#: content_admin.inc:596 +msgid "Added field %label." +msgstr "Aggiunto il campo %label" + +#: content_admin.inc:608 +msgid "The field name %field_name already exists." +msgstr "Il nome del campo %field_name esiste già." + +#: content_admin.inc:612 +msgid "The field name %field_name is invalid." +msgstr "Il nome del campo %field_name non è valido." + +#: content_admin.inc:663 +msgid "Created field %label." +msgstr "Il campo %label è stato creato" + +#: content_admin.inc:685 +msgid "Are you sure you want to remove the field %field?" +msgstr "Sei sicuro di voler eliminare il campo %field?" + +#: content_admin.inc:687 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Se hai lasciato dei dati in questo campo, li perderai. Questa azione non può essere annullata." + +#: content_admin.inc:688 +#: fieldgroup.module:216 +msgid "Remove" +msgstr "Elimina" + +#: content_admin.inc:688 +#: fieldgroup.module:216 +msgid "Cancel" +msgstr "Cancella" + +#: content_admin.inc:706 +msgid "Removed field %field from %type." +msgstr "Elimina il campo %field da %$type." + +#: content_admin.inc:729 +msgid "Widget settings" +msgstr "Impostazioni widget" + +#: content_admin.inc:730 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Queste impostazioni sono applicate solo al campo %field in quanto appartiene al tipo di contenuto %type." + +#: content_admin.inc:744 +msgid "Widget" +msgstr "Widget" + +#: content_admin.inc:765 +#: fieldgroup.module:106 +msgid "Help text" +msgstr "Testo di aiuto" + +#: content_admin.inc:768 +msgid "Instructions to present to the user below this field on the editing form." +msgstr "Istruzioni da presentare all'utente sotto questo campo nel form di editing" + +#: content_admin.inc:777 +msgid "Default value" +msgstr "Valore di default" + +#: content_admin.inc:800 +#: number.module:65 +#: text.module:49 +msgid "Php code" +msgstr "Codice PHP" + +#: content_admin.inc:812 +#: number.module:71 +#: text.module:55 +msgid "Code" +msgstr "Codice" + +#: content_admin.inc:816 +msgid "Advanced Usage Only: PHP code that returns a default value. Should not include <?php ?> delimiters.<br/>If this field is filled out, the value returned by this code will override any value in the textfield above.<br/>Expected format : @sample." +msgstr "Esclusivo per l'uso avanzato: il codice PHP che restituisce un valore di default non dovrebbe includere i delimitatori <?php ?>.<br/>Se questo campo venisse riempito, il valore restituito dal codice sovrascriverà tutti i valori inseriti nei campi di testo precedenti.<br/> Formattazione attesa : @sample" + +#: content_admin.inc:822 +msgid "Data settings" +msgstr "Impostazioni della data" + +#: content_admin.inc:823 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Queste impostazioni verranno applicate al campo %field in ogni tipo di contenuto in cui esso appare." + +#: content_admin.inc:827 +msgid "Required" +msgstr "Richiesto" + +#: content_admin.inc:832 +msgid "Multiple values" +msgstr "Valori multipli" + +#: content_admin.inc:843 +msgid "Save field settings" +msgstr "Salva le impostazioni del campo" + +#: content_admin.inc:903 +msgid "The default value php code returned an incorrect value<br/>Expected format : @sample<br/>Returned value : @value" +msgstr "Il codice PHP per il valore di default ha restituito un valore errato<br/>Formato atteso : @sample<br/>Valore restituito : @value" + +#: content_admin.inc:941 +msgid "The default value php code created @value which is invalid." +msgstr "Il codice PHP per il valore di default ha creato @value che non è valido." + +#: content_admin.inc:944 +msgid "The default value is invalid." +msgstr "Il valore di default è invalido." + +#: content_admin.inc:1001 +msgid "Saved field %field." +msgstr "Il campo %field è stato salvato." + +#: content_admin.inc:1292 +msgid "No PostgreSQL mapping found for %type data type." +msgstr "Non è stato trovato alcun mapping PostgreSQL per il tipo di dato %type." + +#: content_admin.inc:1292 +msgid "database" +msgstr "database" + +#: content_crud.inc:59 +msgid "The content fields table %name has been created." +msgstr "La tabella dei contenuti dei campi %name è stata creata." + +#: content_crud.inc:89 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "La tabella dei contenuti dei campi %old_name è stata rinominata in %new_name e le istanze dei campi sono state aggiornate." + +#: content_crud.inc:111 +msgid "The content fields table %name has been deleted." +msgstr "La tabella dei contenuti dei campi %name è stata eliminata." + +#: content_views.inc:70 +msgid "Group multiple values" +msgstr "Raggruppa i valori multipli" + +#: content_views.inc:71 +msgid "Do not group multiple values" +msgstr "Non raggruppare i valori multipli." + +#: content.module:18 +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "Imposta come il tipo di contenuto del campo e la sua etichetta vengono visualizzati quando sono visualizzati nell'anteprima e a pagina piena." + +#: content.module:67 +#: content_copy.module:129 +msgid "Fields" +msgstr "Campi" + +#: content.module:83 +msgid "Edit" +msgstr "Modifica" + +#: content.module:90 +msgid "Manage fields" +msgstr "Gestisci campi" + +#: content.module:99 +msgid "Display fields" +msgstr "Visualizza campi" + +#: content.module:127 +msgid "Remove field" +msgstr "Rimuovi campi" + +#: content.module:0 +msgid "content" +msgstr "contenuto" + +#: content_copy.module:35 +msgid "Export" +msgstr "Esporta" + +#: content_copy.module:44 +msgid "Import" +msgstr "Importa" + +#: content_copy.module:81 +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "Questo modulo analizzerà un tipo di contenuto ed uno o più campi dello stesso tipo esportandone le impostazioni. L'esportazione così creata può essere copiata ed incollata, come importazione, nel database corrente o in qualsiasi altro. L'importazione aggiungerà i campi in un tipo di contenuto esistente oppure creerà un nuovo tipo di contenuto includente i campi selezionati." + +#: content_copy.module:90 +msgid "Types" +msgstr "Tipi" + +#: content_copy.module:94 +msgid "Select the content type to export." +msgstr "Seleziona il tipo di contenuto da esportare." + +#: content_copy.module:119 +msgid "Groups" +msgstr "Gruppi" + +#: content_copy.module:123 +msgid "Select the group definitions to export from %type." +msgstr "Seleziona le definizioni del gruppo da esportare da %type." + +#: content_copy.module:133 +msgid "Select the field definitions to export from %type." +msgstr "Seleziona le definizioni del campo da esportare da %type." + +#: content_copy.module:143 +msgid "Export data" +msgstr "Esporta dati" + +#: content_copy.module:148 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Copia il testo esportato ed incollalo in un altro tipo di contenuto usanto la funzione importa." + +#: content_copy.module:214 +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "Questo modulo importerà le definizioni del campo esportate da un altro tipo di contenuto o da un altro database.<br/>Ricorda che i campi non possono essere duplicati con lo stesso tipo di contenuto, quindi i campi importati verranno aggiunti solo se non esistenti nel tipo selezionato." + +#: content_copy.module:217 +msgid "<Create>" +msgstr "<Crea>" + +#: content_copy.module:219 +msgid "Content type" +msgstr "Tipo di contenuto" + +#: content_copy.module:220 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Seleziona il tipo di contenuto nel quale importare i campi.<br/>Seleziona <Crea> per creare un nuovo tipo di contenuto per i campi." + +#: content_copy.module:225 +msgid "Import data" +msgstr "Importa dati" + +#: content_copy.module:227 +msgid "Paste the text created by a content export into this field." +msgstr "Incolla il testo esportato da un contenuto in questo campo." + +#: content_copy.module:255 +msgid "The import data is not valid import text." +msgstr "I dati dell'importazione non sono validi." + +#: content_copy.module:300 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "I seguenti moduli devono essere abilitati per permettere l'importazione: %modules." + +#: content_copy.module:306 +msgid "<create>" +msgstr "<crea>" + +#: content_copy.module:308 +msgid "The content type %type already exists in this database." +msgstr "Il tipo di contenuto %type esiste già in questo database." + +#: content_copy.module:315 +msgid "Exiting. No import performed." +msgstr "Chiusura in corso. Nessun dato importato." + +#: content_copy.module:332 +msgid "An error has occured adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Errore nell'aggiunta del tipo di contenuto %type.<br/>Controlla gli errori mostrati per maggiori informazioni." + +#: content_copy.module:367 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "Il campo %field_label importato non è stato aggiunto a %type perché è già presente." + +#: content_copy.module:388 +msgid "An error has occured adding the field %field_label (%field_name).<br/>Please check the errors displayed for more details." +msgstr "Errore nell'aggiunta del campo %field_label (%field_name).<br/>Controlla gli errori mostrati per maggiori informazioni." + +#: content_copy.module:421 +msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field settings.<br/>Please check the errors displayed for more details." +msgstr "Il campo %field_label (%field_name) è stato aggiunto al tipo di contenuto %type, ma c'è stato un errore aggiornando le impostazioni del campo.<br/>Controlla gli errori mostrati per maggiori informazioni." + +#: content_copy.module:0 +msgid "content_copy" +msgstr "copia_contenuto" + +#: fieldgroup.module:18 +msgid "Add group" +msgstr "Aggiungi gruppo" + +#: fieldgroup.module:28 +msgid "Edit group" +msgstr "Modifica gruppo" + +#: fieldgroup.module:66 +msgid "Add" +msgstr "Aggiungi" + +#: fieldgroup.module:73 +msgid "Save" +msgstr "Salva" + +#: fieldgroup.module:92 +msgid "These settings apply to the group in the node editing form" +msgstr "Queste impostazioni sono applicate al gruppo nella scheda di modifica dei nodi." + +#: fieldgroup.module:96 +msgid "style" +msgstr "stile" + +#: fieldgroup.module:99 +msgid "always open" +msgstr "sempre aperto" + +#: fieldgroup.module:100 +msgid "collapsible" +msgstr "espandibile" + +#: fieldgroup.module:101 +msgid "collapsed" +msgstr "espanso" + +#: fieldgroup.module:109 +msgid "Instructions to present to the user on the editing form." +msgstr "Istruzioni da mostrare all'utente nella scheda di modifica." + +#: fieldgroup.module:115 +msgid "These settings apply to the group on node display." +msgstr "Queste impostazioni sono applicate al gruppo nel visualizza nodi." + +#: fieldgroup.module:119 +msgid "Description" +msgstr "Descrizione" + +#: fieldgroup.module:122 +msgid "A description of the group." +msgstr "Descrizione del gruppo." + +#: fieldgroup.module:144 +msgid "The group name %name already exists." +msgstr "Il nome del gruppo %name esiste già." + +#: fieldgroup.module:148 +msgid "The group name %name is invalid." +msgstr "Il nome del gruppo %name non è valido." + +#: fieldgroup.module:213 +msgid "Are you sure you want to remove the group %label?" +msgstr "Sei sicuro di voler rimuovere il gruppo %label?" + +#: fieldgroup.module:215 +msgid "This action cannot be undone." +msgstr "Questa azione non può essere annullata." + +#: fieldgroup.module:277 +msgid "No group" +msgstr "Nessun gruppo" + +#: fieldgroup.module:320 +msgid "Display in group" +msgstr "Visualizza in gruppi" + +#: fieldgroup.module:323 +msgid "Select a group, in which the field will be displayed on the editing form." +msgstr "Seleziona un gruppo, del quale verrà mostrato il campo nella scheda di modifica." + +#: fieldgroup.module:482 +msgid "no styling" +msgstr "nessuno stile" + +#: fieldgroup.module:483 +msgid "simple" +msgstr "semplice" + +#: fieldgroup.module:484 +msgid "fieldset" +msgstr "impostacampo" + +#: fieldgroup.module:485 +msgid "fieldset - collapsible" +msgstr "impostacampo - espandibile" + +#: fieldgroup.module:486 +msgid "fieldset - collapsed" +msgstr "impostacampo - espanso" + +#: fieldgroup.module:0 +msgid "fieldgroup" +msgstr "gruppocampo" + +#: nodereference.module:17 +msgid "node reference autocomplete" +msgstr "autocompletamento referenza nodo" + +#: nodereference.module:42 +msgid "Content types that can be referenced" +msgstr "Tipi di contenuto che possono essere usati come riferimento" + +#: nodereference.module:51 +msgid "Existing Views" +msgstr "Viste Attuali" + +#: nodereference.module:56 +msgid "Default Views" +msgstr "Viste di default" + +#: nodereference.module:61 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Avanzato - Nodi che possono venir usati come riferimento (Visualizza)" + +#: nodereference.module:67 +msgid "View" +msgstr "Vista" + +#: nodereference.module:70 +msgid "Choose the \"Views module\" view that selects the nodes that can be referenced.<br>Note :<ul><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "Scegli la vista del \"modulo Views\" che seleziona i tipi di nodo che possono essere riferiti.<br>Nota:<ul><li>Questo escludera' le precedenti impostazioni riguardanti i \"tipi di Contenuto\". Utilizza piuttosto i \"filtri\" del modulo vista.</li><li>Utilizza i \"campi\" vista per visualizzare informazioni addizionali sui nodi candidati nella form per la creazione/modifica dei nodi.</li><li>Utilizza i \"criteri di ordinazione\" per determinare l'ordine in cui i nodi candidati verranno visualizzati</li></ul>" + +#: nodereference.module:74 +msgid "View arguments" +msgstr "Argomenti vista" + +#: nodereference.module:77 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Inserisci una lista di argomenti separati da virgola da passare alla vista." + +#: nodereference.module:122 +msgid "%name : This post can't be referenced." +msgstr "%name : Questo post non può venir usato come riferimento." + +#: nodereference.module:202 +#: userreference.module:142 +msgid "<none>" +msgstr "<nulla>" + +#: nodereference.module:304 +msgid "%name : Title mismatch. Please check your selection." +msgstr "%name : Titolo non adatto. Ricontrolla la tua selezione." + +#: nodereference.module:483 +msgid "<empty>" +msgstr "<vuoto>" + +#: nodereference.module:0 +msgid "nodereference" +msgstr "riferimento nodo" + +#: number.module:33 +msgid "Minimum" +msgstr "Minimo" + +#: number.module:38 +msgid "Maximum" +msgstr "Massimo" + +#: number.module:43 +msgid "Prefix" +msgstr "Prefisso" + +#: number.module:46 +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Definisci una stringa che può essere anteposta al valore, come $ o €. Altrimenti lascia vuoto. Separa i valori singolari e plurali con un pipe (lira|lire)." + +#: number.module:50 +msgid "Suffix" +msgstr "Suffisso" + +#: number.module:53 +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds). " +msgstr "Definisci una stringa che può essere posposta al valore, come $ o €. Altrimenti lascia vuoto. Separa i valori singolari e plurali con un pipe (lira|lire)." + +#: number.module:57 +#: text.module:41 +msgid "Allowed values list" +msgstr "Lista di valori ammessi" + +#: number.module:61 +#: text.module:45 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database and it must match the field storage type, %type. The label is optional and the key will be used as the label if no label is specified." +msgstr "I possibili valori che questo campo può contenere. Inserisci un valore per linea, nella forma chiave|etichetta. La chiave è il valore che verrà memorizzato nel database e deve corrispondere al tipo di campo salvato, %type. L'etichetta è un optional e la chiave sarà usata al suo posto se non verrà specificata." + +#: number.module:74 +#: text.module:58 +msgid "Advanced Usage Only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Solamente per l'Utilizzo Avanzato: il codice PHP che ritorna un array con chiavi di valori permessi. Non dovrebbe includere i delimitatori <?php ?>. Se questo campo viene riempito, l'array in ritorno da questo codice annullera' i valori elencati sopra." + +#: number.module:80 +msgid "\"Minimum\" must be a number." +msgstr "\"Minimo\" deve essere un numero." + +#: number.module:83 +msgid "\"Maximum\" must be a number." +msgstr "\"Massimo\" deve essere un numero." + +#: number.module:138 +msgid "The value of %name may be no smaller than %min." +msgstr "Il valore di %name non dovrebbe essere minore di %min." + +#: number.module:141 +msgid "The value of %name may be no larger than %max." +msgstr "Il valore di %name non dovrebbe essere maggiore di %max." + +#: number.module:0 +msgid "number" +msgstr "numero" + +#: optionwidgets.module:38 +msgid "Create a list of options as a list in <strong>Allowed values</strong> or as an array in Php code at the bottom of this page. These values will be the same for the %field in all content types. " +msgstr "Crea una lista di opzioni come lista in <strong>Valori validi</strong> o come array in codice PHP alla fine della pagina. Questi valori saranno gli stessi per il campo %field in tutti i tipi di contenuto." + +#: optionwidgets.module:40 +msgid " For a single on/off checkbox, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section." +msgstr "Per una singola checkbox on/off, definisci prima il valore 'off' e successivamente il valore 'on' nella sezione <strong>Valori validi</strong>." + +#: optionwidgets.module:43 +msgid " The Check boxes/radio buttons widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "I pulsanti delle Check/Radio boxes all'interno delle widget visualizzeranno delle checkboxes se l'opzione \"valori multipli\" e' attiva, altrimenti, verranno visualizzate delle radioboxes." + +#: optionwidgets.module:206 +msgid "N/A" +msgstr "N/A" + +#: optionwidgets.module:0 +msgid "optionwidgets" +msgstr "widgetopzioni" + +#: text.module:25 +msgid "Plain text" +msgstr "Testo normale" + +#: text.module:25 +msgid "Filtered text (user selects input format)" +msgstr "Testo filtrato (l'utente seleziona il formato di ingresso)" + +#: text.module:28 +msgid "Text processing" +msgstr "Analisi del testo" + +#: text.module:127 +msgid "%label is longer than %max characters." +msgstr "%label supera i %max caratteri." + +#: text.module:0 +msgid "text" +msgstr "testo" + +#: userreference.module:27 +msgid "User roles that can be referenced" +msgstr "Regole utente che possono venir usate come riferimento." + +#: userreference.module:65 +msgid "%name : Invalid user." +msgstr "%name : utente non valido." + +#: userreference.module:0 +msgid "userreference" +msgstr "riferimento utente" + +#: optionwidgets.install:77 +msgid "<div>The allowed values list for %field was updated from </div><pre>%start</pre><div> to </div><pre>%end</pre><div>You can go to the field settings page to give each option a more user-friendly label." +msgstr "<div>La lista sei valori ammessi per %field è stata aggiornata dal </div><pre>%start</pre><div> al </div><pre>%end</pre><div>Puoi andare nella pagina delle impostazioni del campo per assegnare a ciascuna opzione una miglior etichetta." + +#: optionwidgets.install:80 +msgid "<div>The allowed values list for %field was not changed from </div><pre>%start</pre>" +msgstr "<div>La lista sei valori ammessi per %field non è stata cambiata dal </div><pre>%start</pre><div> " + +#: content.info:0 +msgid "Content" +msgstr "Contenuto" + +#: content.info:0 +msgid "Allows administrators to define new content types." +msgstr "Permetti agli amministratori di definire nuovi tipi di contenuto." + +#: content.info:0 +#: content_copy.info:0 +#: fieldgroup.info:0 +#: nodereference.info:0 +#: number.info:0 +#: optionwidgets.info:0 +#: text.info:0 +#: userreference.info:0 +msgid "CCK" +msgstr "CCK" + +#: content_copy.info:0 +msgid "Content Copy" +msgstr "Copia contenuto" + +#: content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "Abilita la possibilità di importare/esportare le definizioni del campo." + +#: fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "CampoGruppo" + +#: fieldgroup.info:0 +msgid "Create field groups for CCK fields." +msgstr "Crea un campo di gruppi per i campi CCK" + +#: nodereference.info:0 +msgid "Node Reference" +msgstr "Riferimento Nodo" + +#: nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "Definisce un tipo di campo come riferimento da un nodo ad un altro." + +#: number.info:0 +msgid "Number" +msgstr "Numero" + +#: number.info:0 +msgid "Defines numeric field types." +msgstr "Definisce i tipi di campo numerici." + +#: optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Opzioni Widgets" + +#: optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "Definisce la selezione, i widgets check box e radio button per il testo e per i campi numerici." + +#: text.info:0 +msgid "Text" +msgstr "Testo" + +#: text.info:0 +msgid "Defines simple text field types." +msgstr "Definisce dei semplici tipi di campo testo." + +#: userreference.info:0 +msgid "User Reference" +msgstr "Riferimento Utente" + +#: userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "Definisce un tipo di campo come riferimento per un utente da un nodo." + +#: theme/node-content_example.tpl.php:10 +msgid "!date — !username" +msgstr "!date — !username" diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/ja.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/ja.po new file mode 100644 index 0000000000000000000000000000000000000000..a7679c311b1adddb8a96dd4f9a77e2dd8baee22c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/ja.po @@ -0,0 +1,1278 @@ +# $Id$ +# +# Japanese translation of Drupal (cck) +# Copyright 2008 0829 <hixarg+0829@gmail.com> +# Generated from files: +# userreference.info,v 1.8 2008/04/23 18:02:38 dww Exp +# userreference.module,v 1.106 2008/06/01 22:00:36 karens Exp +# text.info,v 1.9 2008/04/23 18:02:31 dww Exp +# text.module,v 1.95 2008/06/01 21:59:56 karens Exp +# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww Exp +# optionwidgets.module,v 1.69 2008/06/03 12:25:45 karens Exp +# number.info,v 1.7 2008/04/23 18:02:16 dww Exp +# number.module,v 1.91 2008/05/13 16:40:00 karens Exp +# nodereference.info,v 1.8 2008/04/23 18:02:07 dww Exp +# nodereference.module,v 1.138 2008/05/31 18:12:50 karens Exp +# fieldgroup.info,v 1.6 2008/04/23 18:01:58 dww Exp +# fieldgroup.module,v 1.79 2008/06/02 16:33:20 karens Exp +# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww Exp +# content_permissions.install,v 1.1 2008/04/25 02:03:14 karens Exp +# content_permissions.module,v 1.5 2008/05/11 19:20:09 dopry Exp +# content_copy.info,v 1.6 2008/04/23 18:01:48 dww Exp +# content_copy.module,v 1.27 2008/05/29 22:27:04 karens Exp +# content.admin.inc,v 1.181 2008/06/03 12:25:44 karens Exp +# content.crud.inc,v 1.76 2008/06/03 14:16:55 karens Exp +# content.node_form.inc,v 1.7 2008/05/28 20:40:45 karens Exp +# content.token.inc,v 1.5 2008/04/25 01:24:40 karens Exp +# content.views.inc,v 1.68 2008/05/29 11:16:14 karens Exp +# example_field.php,v 1.5 2008/04/23 08:24:06 karens Exp +# simple_field.php,v 1.5 2008/04/23 08:24:06 karens Exp +# content.info,v 1.6 2007/07/04 23:46:29 yched Exp +# content.module,v 1.301 2008/06/03 12:52:23 karens Exp +# +msgid "" +msgstr "" +"Project-Id-Version: Drupal 6.x\n" +"POT-Creation-Date: 2008-06-06 11:21+0900\n" +"PO-Revision-Date: 2008-06-13 11:29+0900\n" +"Last-Translator: 0829 <hixarg+0829@gmail.com>\n" +"Language-Team: DRUPAL*DRUPAL <hixarg+0829@gmail.com>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: modules/cck/modules/userreference/userreference.info:0 +msgid "User Reference" +msgstr "ユーザ参照" + +#: modules/cck/modules/userreference/userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "ユーザを参照するためのフィールドタイプを定義します。" + +#: modules/cck/modules/userreference/userreference.info:0 +#: modules/cck/modules/text/text.info:0 +#: modules/cck/modules/optionwidgets/optionwidgets.info:0 +#: modules/cck/modules/number/number.info:0 +#: modules/cck/modules/nodereference/nodereference.info:0 +#: modules/cck/modules/fieldgroup/fieldgroup.info:0 +#: modules/cck/modules/content_permissions/content_permissions.info:0 +#: modules/cck/modules/content_copy/content_copy.info:0 +#: modules/cck/content.info:0 +msgid "CCK" +msgstr "CCK" + +#: modules/cck/modules/userreference/userreference.module:52 +msgid "User reference" +msgstr "ユーザ参照" + +#: modules/cck/modules/userreference/userreference.module:53 +msgid "Store the ID of a related user as an integer value." +msgstr "参照ユーザの ID を整数の値としてデータベースに保存します。" + +#: modules/cck/modules/userreference/userreference.module:71 +msgid "User roles that can be referenced" +msgstr "参照するロール" + +#: modules/cck/modules/userreference/userreference.module:77 +msgid "User status that can be referenced" +msgstr "参照を可能とするユーザの状態" + +#: modules/cck/modules/userreference/userreference.module:79 +msgid "Active" +msgstr "アクティブ" + +#: modules/cck/modules/userreference/userreference.module:79 +msgid "Blocked" +msgstr "ブロック" + +#: modules/cck/modules/userreference/userreference.module:122 +msgid "%name: Invalid user." +msgstr "%name: 無効なユーザです。" + +#: modules/cck/modules/userreference/userreference.module:146 +#: modules/cck/modules/text/text.module:194 +#: modules/cck/examples/example_field.php:383 +#: modules/cck/examples/simple_field.php:327 +msgid "Default" +msgstr "デフォルト" + +#: modules/cck/modules/userreference/userreference.module:151 +#: modules/cck/modules/text/text.module:66;199 +#: modules/cck/examples/example_field.php:158;388 +#: modules/cck/examples/simple_field.php:332 +msgid "Plain text" +msgstr "プレーンテキスト" + +#: modules/cck/modules/userreference/userreference.module:198 +#: modules/cck/modules/optionwidgets/optionwidgets.module:62 +#: modules/cck/modules/nodereference/nodereference.module:303 +msgid "Select list" +msgstr "選択リスト" + +#: modules/cck/modules/userreference/userreference.module:206 +#: modules/cck/modules/nodereference/nodereference.module:311 +msgid "Autocomplete text field" +msgstr "オートコンプリートテキストフィールド" + +#: modules/cck/modules/userreference/userreference.module:253 +msgid "Reverse link" +msgstr "バックリンク" + +#: modules/cck/modules/userreference/userreference.module:255 +msgid "No" +msgstr "いいえ" + +#: modules/cck/modules/userreference/userreference.module:255 +msgid "Yes" +msgstr "はい" + +#: modules/cck/modules/userreference/userreference.module:257 +msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record." +msgstr "有効にした場合、ノードから参照されたユーザのアカウントページに参照元ノードへのバックリンクが表示されます。" + +#: modules/cck/modules/userreference/userreference.module:439 +#: modules/cck/modules/nodereference/nodereference.module:544 +#: modules/cck/modules/fieldgroup/fieldgroup.module:289 +msgid "none" +msgstr "なし" + +#: modules/cck/modules/userreference/userreference.module:586 +msgid "Related content" +msgstr "関連するコンテンツ" + +#: modules/cck/modules/userreference/userreference.module:15 +msgid "Userreference autocomplete" +msgstr "ユーザ参照オートコンプリート" + +#: modules/cck/modules/userreference/userreference.module:0 +msgid "userreference" +msgstr "ユーザ参照" + +#: modules/cck/modules/text/text.info:0 +#: modules/cck/modules/text/text.module:49 +#: modules/cck/examples/example_field.php:107 +#: modules/cck/examples/simple_field.php:115 +msgid "Text" +msgstr "テキスト" + +#: modules/cck/modules/text/text.info:0 +msgid "Defines simple text field types." +msgstr "シンプルなテキストのフィールドタイプを定義します。" + +#: modules/cck/modules/text/text.module:50 +msgid "Store text in the database." +msgstr "テキストをデータベースに保存します。" + +#: modules/cck/modules/text/text.module:66 +#: modules/cck/examples/example_field.php:158 +msgid "Filtered text (user selects input format)" +msgstr "フィルタされたテキスト(選択した入力書式)" + +#: modules/cck/modules/text/text.module:69 +#: modules/cck/examples/example_field.php:161 +msgid "Text processing" +msgstr "テキストの処理" + +#: modules/cck/modules/text/text.module:75 +#: modules/cck/examples/example_field.php:167 +#: modules/cck/examples/simple_field.php:164 +msgid "Maximum length" +msgstr "最大文字長" + +#: modules/cck/modules/text/text.module:78 +#: modules/cck/examples/example_field.php:170 +#: modules/cck/examples/simple_field.php:167 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "フィールドで使用可能な文字列の最大の長さです。 入力できる文字数を無制限にしたい場合は空欄にしてください。" + +#: modules/cck/modules/text/text.module:82 +#: modules/cck/modules/number/number.module:123 +msgid "Allowed values" +msgstr "使用する値" + +#: modules/cck/modules/text/text.module:88 +#: modules/cck/modules/number/number.module:129 +#: modules/cck/examples/example_field.php:174 +msgid "Allowed values list" +msgstr "使用する値のリスト" + +#: modules/cck/modules/text/text.module:92 +#: modules/cck/modules/number/number.module:133 +#: modules/cck/examples/example_field.php:178 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database and it must match the field storage type, %type. The label is optional and the key will be used as the label if no label is specified." +msgstr "このフィールドで使用する値のリストを、1行あたり 1つの値として \"キー|ラベル\" という形式で入力してください。 キーはデータベースに格納される値になりますのでフィールドの型が %type と一致していなければなりません。 また、ラベルはオプションの設定項目ですので、ラベルを指定しない場合はキーがラベルとして利用されます。" + +#: modules/cck/modules/text/text.module:96 +#: modules/cck/modules/number/number.module:137 +#: modules/cck/includes/content.admin.inc:879 +#: modules/cck/examples/example_field.php:182 +msgid "PHP code" +msgstr "PHP コード" + +#: modules/cck/modules/text/text.module:102 +#: modules/cck/modules/number/number.module:143 +#: modules/cck/includes/content.admin.inc:897 +#: modules/cck/examples/example_field.php:188 +msgid "Code" +msgstr "コード" + +#: modules/cck/modules/text/text.module:105 +#: modules/cck/modules/number/number.module:146 +#: modules/cck/examples/example_field.php:191 +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "PHP に精通した方専用: 使用する値のキー配列として返す PHP コードを <?php ?> を含めずに記入してください。 このフィールドが入力されている場合、このコードによって返される値は上記で設定した使用する値のリストを上書きします。" + +#: modules/cck/modules/text/text.module:150 +#: modules/cck/modules/number/number.module:218 +#: modules/cck/examples/example_field.php:278 +msgid "Illegal value for %name." +msgstr "%name の規則に反している値です。" + +#: modules/cck/modules/text/text.module:159 +#: modules/cck/examples/example_field.php:287 +#: modules/cck/examples/simple_field.php:231 +msgid "%label is longer than %max characters." +msgstr "%label が %max 文字を超えています。" + +#: modules/cck/modules/text/text.module:204 +#: modules/cck/examples/example_field.php:393 +msgid "Trimmed" +msgstr "トリミング" + +#: modules/cck/modules/text/text.module:254 +#: modules/cck/modules/number/number.module:332 +#: modules/cck/examples/example_field.php:476 +#: modules/cck/examples/simple_field.php:400 +msgid "Text field" +msgstr "テキストフィールド" + +#: modules/cck/modules/text/text.module:262 +msgid "Text area (multiple rows)" +msgstr "テキストエリア(複数行)" + +#: modules/cck/modules/text/text.module:314 +#: modules/cck/examples/example_field.php:551 +#: modules/cck/examples/simple_field.php:430 +msgid "Rows" +msgstr "行数" + +#: modules/cck/modules/text/text.module:323 +#: modules/cck/examples/example_field.php:560 +#: modules/cck/examples/simple_field.php:438 +msgid "\"Rows\" must be a positive integer." +msgstr "\"行数\" は正の整数でなければなりません。" + +#: modules/cck/modules/text/text.module:0 +msgid "text" +msgstr "テキスト" + +#: modules/cck/modules/optionwidgets/optionwidgets.info:0 +msgid "Option Widgets" +msgstr "オプションウィジェット" + +#: modules/cck/modules/optionwidgets/optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "テキストと数値のフィールドタイプにチェックボックスやラジオボタンの選択ウィジェットを定義します。" + +#: modules/cck/modules/optionwidgets/optionwidgets.module:10 +msgid "Create a list of options as a list in <strong>Allowed values</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "<strong>使用する値のリスト</strong> または PHP コードを利用してオプションのリストを作成してください。 設定したリストの値は %field フィールドが表示されるすべてのコンテンツタイプで適用されます。" + +#: modules/cck/modules/optionwidgets/optionwidgets.module:12 +msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "'シングル ON/OFF チェックボックス' ウィジェットを利用する場合は、最初に 'OFF' の値、次に 'ON' の値の順で、<strong>使用する値のリスト</strong>セクションに定義します。 このチェックボックスでは、'ON' の値のラベルがラベルとして使用されることに注意してください。" + +#: modules/cck/modules/optionwidgets/optionwidgets.module:15 +msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "'チェックボックス/ラジオボタン' ウィジェットでは、複数選択のオプションが設定されている場合はチェックボックスが、そうでない場合にはラジオボタンが表示されます。" + +#: modules/cck/modules/optionwidgets/optionwidgets.module:70 +msgid "Check boxes/radio buttons" +msgstr "チェックボックス/ラジオボタン" + +#: modules/cck/modules/optionwidgets/optionwidgets.module:78 +msgid "Single on/off checkbox" +msgstr "シングル ON/OFF チェックボックス" + +#: modules/cck/modules/optionwidgets/optionwidgets.module:364 +msgid "N/A" +msgstr "N/A" + +#: modules/cck/modules/optionwidgets/optionwidgets.module:0 +msgid "optionwidgets" +msgstr "オプションウィジェット" + +#: modules/cck/modules/number/number.info:0 +msgid "Number" +msgstr "数値" + +#: modules/cck/modules/number/number.info:0 +msgid "Defines numeric field types." +msgstr "数値のフィールドタイプを定義します。" + +#: modules/cck/modules/number/number.module:41 +msgid "Integer" +msgstr "整数" + +#: modules/cck/modules/number/number.module:42 +msgid "Store a number in the database as an integer." +msgstr "数字を整数の値としてデータベースに保存します。" + +#: modules/cck/modules/number/number.module:49 +msgid "Decimal" +msgstr "小数" + +#: modules/cck/modules/number/number.module:50 +msgid "Store a number in the database in a fixed decimal format." +msgstr "数字を小数の値としてデータベースに保存します。" + +#: modules/cck/modules/number/number.module:57 +msgid "Float" +msgstr "浮動小数点数" + +#: modules/cck/modules/number/number.module:58 +msgid "Store a number in the database in a floating point format." +msgstr "数字を浮動小数点数の値としてデータベースに保存します。" + +#: modules/cck/modules/number/number.module:76 +msgid "Minimum" +msgstr "最小値" + +#: modules/cck/modules/number/number.module:81 +msgid "Maximum" +msgstr "最大値" + +#: modules/cck/modules/number/number.module:88 +msgid "Precision" +msgstr "精度" + +#: modules/cck/modules/number/number.module:89 +msgid "The total number of digits to store in the database, including those to the right of the decimal." +msgstr "データベースに保存する桁数の総数(小数点以下の桁数と小数点記号を含む)を選択してください。" + +#: modules/cck/modules/number/number.module:95 +msgid "Scale" +msgstr "スケール" + +#: modules/cck/modules/number/number.module:96 +msgid "The number of digits to the right of the decimal." +msgstr "小数点以下の桁数を選択してください。" + +#: modules/cck/modules/number/number.module:102 +msgid "Decimal marker" +msgstr "小数点記号" + +#: modules/cck/modules/number/number.module:103 +msgid "The character users will input to mark the decimal point in forms." +msgstr "フォーム内に入力された内容の小数点を評価するために利用する記号を選択してください。" + +#: modules/cck/modules/number/number.module:109 +msgid "Prefix" +msgstr "接頭語" + +#: modules/cck/modules/number/number.module:112 +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "値に接頭語として付記する $ や € のような記号を定義してください。 接頭語を付記しない場合は空欄にしてください。 単数形と複数形は、'pound|pounds' のようにパイプ(|)で区切って入力します。" + +#: modules/cck/modules/number/number.module:116 +msgid "Suffix" +msgstr "接尾語" + +#: modules/cck/modules/number/number.module:119 +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "値に接尾語として付記する m², m/s², kb/s のような記号を定義してください。 接尾語を付記しない場合は空欄にしてください。 単数形と複数形は、'pound|pounds' のようにパイプ(|)で区切って入力します。" + +#: modules/cck/modules/number/number.module:152 +msgid "\"Minimum\" must be a number." +msgstr "\"最小値\" は数値でなければなりません。" + +#: modules/cck/modules/number/number.module:155 +msgid "\"Maximum\" must be a number." +msgstr "\"最大値\" は数値でなければなりません。" + +#: modules/cck/modules/number/number.module:212 +msgid "The value of %name may be no smaller than %min." +msgstr "%name には %min 未満の値を入力することはできません。" + +#: modules/cck/modules/number/number.module:215 +msgid "The value of %name may be no larger than %max." +msgstr "%name には %max より大きい値を入力することはできません。" + +#: modules/cck/modules/number/number.module:253 +msgid "unformatted" +msgstr "フォーマットなし" + +#: modules/cck/modules/number/number.module:466 +msgid "Only numbers and decimals are allowed in %field. %start was changed to %value." +msgstr "%field フィールドには、数字(小数を含む)のみが入力できます。 %start は %value に変更されました。" + +#: modules/cck/modules/number/number.module:484 +msgid "Only numbers are allowed in %field. %start was changed to %value." +msgstr "%field フィールドには、数字のみが入力できます。 %start は %value に変更されました。" + +#: modules/cck/modules/number/number.module:503 +msgid "Only numbers and the decimal character (%decimal) are allowed in %field. %start was changed to %value." +msgstr "%field フィールドには、数字と小数点記号(%decimal)のみが入力できます。 %start は %value に変更されました。" + +#: modules/cck/modules/number/number.module:0 +msgid "number" +msgstr "数値" + +#: modules/cck/modules/nodereference/nodereference.info:0 +msgid "Node Reference" +msgstr "ノード参照" + +#: modules/cck/modules/nodereference/nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "他のノードを参照するためのフィールドタイプを定義します。" + +#: modules/cck/modules/nodereference/nodereference.module:71 +msgid "Node reference" +msgstr "ノード参照" + +#: modules/cck/modules/nodereference/nodereference.module:72 +msgid "Store the ID of a related node as an integer value." +msgstr "参照ノードの ID を整数の値としてデータベースに保存します。" + +#: modules/cck/modules/nodereference/nodereference.module:90 +msgid "Content types that can be referenced" +msgstr "参照するコンテンツタイプ" + +#: modules/cck/modules/nodereference/nodereference.module:101 +msgid "Existing Views" +msgstr "既存のビュー" + +#: modules/cck/modules/nodereference/nodereference.module:108 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "高度な設定 - 参照するノード(ビュー)" + +#: modules/cck/modules/nodereference/nodereference.module:114 +msgid "View" +msgstr "表示" + +#: modules/cck/modules/nodereference/nodereference.module:117 +msgid "Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note :<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "\"ビューモジュール\" で定義されたビューの中から、参照するノードとして表示するものを選択してください。<br />注意 :<ul><li>ノード参照として機能するフィールドを持つビューのみが選択できます。</li><li>ここで設定を行なった場合、上記の \"コンテンツタイプ\" は適用されません。 ビューの \"フィルタ\" セクションで代替となる設定を行ってください。</li><li>コンテンツの作成・編集フォームに参照するノードの追加説明を表示する場合にはビューの \"フィールド\" セクションで設定を行ってください。</li><li>参照するノードの順序を決定する場合にはビューの \"並べ替えの基準\" セクションで設定を行ってください。</li></ul>" + +#: modules/cck/modules/nodereference/nodereference.module:121 +msgid "View arguments" +msgstr "ビューのアーギュメント" + +#: modules/cck/modules/nodereference/nodereference.module:124 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "ビューへ渡すアーギュメントのリストをコンマ(,)で区切って設定してください。" + +#: modules/cck/modules/nodereference/nodereference.module:175 +msgid "%name : This post can't be referenced." +msgstr "%name: この投稿は参照できませんでした。" + +#: modules/cck/modules/nodereference/nodereference.module:200 +msgid "Title (link)" +msgstr "タイトル(リンクあり)" + +#: modules/cck/modules/nodereference/nodereference.module:205 +msgid "Title (no link)" +msgstr "タイトル(リンクなし)" + +#: modules/cck/modules/nodereference/nodereference.module:210 +#: modules/cck/content.module:1612 +msgid "Full node" +msgstr "完全なノード" + +#: modules/cck/modules/nodereference/nodereference.module:215 +#: modules/cck/content.module:1611 +msgid "Teaser" +msgstr "ティーザー" + +#: modules/cck/modules/nodereference/nodereference.module:518 +msgid "%name: Title mismatch. Please check your selection." +msgstr "%name: タイトルが不適当です。 選択内容を確認してください。" + +#: modules/cck/modules/nodereference/nodereference.module:15 +msgid "Nodereference autocomplete" +msgstr "ノード参照オートコンプリート" + +#: modules/cck/modules/nodereference/nodereference.module:0 +msgid "nodereference" +msgstr "ノード参照" + +#: modules/cck/modules/fieldgroup/fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "フィールドグループ" + +#: modules/cck/modules/fieldgroup/fieldgroup.info:0 +msgid "Create field groups for CCK fields." +msgstr "CCK フィールドにフィールドグループを作成します。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:99 +msgid "Add" +msgstr "追加" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:106;359 +#: modules/cck/includes/content.admin.inc:152;353 +msgid "Save" +msgstr "保存" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:117 +#: modules/cck/includes/content.admin.inc:163;364;573;798 +msgid "Label" +msgstr "ラベル" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:125 +msgid "These settings apply to the group in the node editing form." +msgstr "これらの設定は、コンテンツの編集フォームのグループ構成として適用されます。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:129 +msgid "Style" +msgstr "スタイル" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:132 +msgid "always open" +msgstr "常に開く" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:133 +msgid "collapsible" +msgstr "折りたたみ(開)" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:134 +msgid "collapsed" +msgstr "折りたたみ(閉)" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:139 +#: modules/cck/includes/content.admin.inc:846 +msgid "Help text" +msgstr "ヘルプテキスト" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:142 +msgid "Instructions to present to the user on the editing form." +msgstr "フォームの編集時にユーザに表示する説明です。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:148 +msgid "These settings apply to the group on node display." +msgstr "これらの設定は、ノードに表示されるフォームのグループ構成として適用されます。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:152 +msgid "Description" +msgstr "説明" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:155 +msgid "A description of the group." +msgstr "このグループについての説明です。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:190 +msgid "The group name %name already exists." +msgstr "グループ名 %name は既に存在します。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:194 +msgid "The group name %name is invalid." +msgstr "グループ名 %name は無効です。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:229 +msgid "Are you sure you want to remove the group %label?" +msgstr "本当に、%label グループを取り外してよろしいですか?" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:231 +msgid "This action cannot be undone." +msgstr "この操作は元に戻すことができませんので、十分に注意して実行してください。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:232 +#: modules/cck/includes/content.admin.inc:99;115;733 +msgid "Remove" +msgstr "取り外す" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:232 +#: modules/cck/includes/content.admin.inc:733 +msgid "Cancel" +msgstr "キャンセル" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:240 +msgid "The group %group_name has been removed." +msgstr "%group_name グループを取り外しました。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:343 +msgid "Display in group" +msgstr "表示するグループ" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:346 +msgid "Select a group, in which the field will be displayed on the editing form." +msgstr "コンテンツの追加・編集フォームでフィールドをグループ化して表示する場合、そのグループ名を選択してください。" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:29 +msgid "Add group" +msgstr "グループの追加" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:37;44 +msgid "Edit group" +msgstr "グループの編集" + +#: modules/cck/modules/fieldgroup/fieldgroup.module:0 +msgid "fieldgroup" +msgstr "フィールドグループ" + +#: modules/cck/modules/content_permissions/content_permissions.info:0 +msgid "Content Permissions" +msgstr "コンテンツ権限" + +#: modules/cck/modules/content_permissions/content_permissions.info:0 +msgid "Set field-level permissions for CCK fields." +msgstr "CCK フィールドにフィールドレベルの権限を設定します。" + +#: modules/cck/modules/content_permissions/content_permissions.install:7 +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "直ちに<a href=\"!url\">フィールド権限の構成</a>を行ってください。 デフォルトですべてのフィールドがアクセス不可に設定されています。" + +#: modules/cck/modules/content_permissions/content_permissions.module:9 +msgid "edit " +msgstr "編集" + +#: modules/cck/modules/content_permissions/content_permissions.module:9;10 +msgid "field_name" +msgstr "フィールド名" + +#: modules/cck/modules/content_permissions/content_permissions.module:10 +msgid "view " +msgstr "表示" + +#: modules/cck/modules/content_permissions/content_permissions.module:0 +msgid "content_permissions" +msgstr "コンテンツ権限" + +#: modules/cck/modules/content_copy/content_copy.info:0 +msgid "Content Copy" +msgstr "コンテンツコピー" + +#: modules/cck/modules/content_copy/content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "フィールド定義をインポートまたはエクスポートできるようにします。" + +#: modules/cck/modules/content_copy/content_copy.module:80 +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "このフォームでは、コンテンツタイプとフィールドの設定をエクスポートするための処理を行います。 ここでエクスポートされたものを、現在のデータベースまたはその他のデータベースへコピーすることでインポートができます。 インポートでは既存のコンテンツタイプにフィールドを追加したり、選択したフィールドを含む新しいコンテンツタイプを作成したりすることができます。" + +#: modules/cck/modules/content_copy/content_copy.module:86 +msgid "Types" +msgstr "タイプ" + +#: modules/cck/modules/content_copy/content_copy.module:90 +msgid "Select the content type to export." +msgstr "エクスポートするコンテンツタイプを選択してください。" + +#: modules/cck/modules/content_copy/content_copy.module:115 +msgid "Groups" +msgstr "グループ" + +#: modules/cck/modules/content_copy/content_copy.module:119 +msgid "Select the group definitions to export from %type." +msgstr "%type からエクスポートするグループの定義を選択してください。" + +#: modules/cck/modules/content_copy/content_copy.module:125 +#: modules/cck/content.module:119 +msgid "Fields" +msgstr "フィールド" + +#: modules/cck/modules/content_copy/content_copy.module:129 +msgid "Select the field definitions to export from %type." +msgstr "%type からエクスポートするフィールドの定義を選択してください。" + +#: modules/cck/modules/content_copy/content_copy.module:139 +msgid "Export data" +msgstr "エクスポートデータ" + +#: modules/cck/modules/content_copy/content_copy.module:144 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "エクスポートされたテキストをコピーして、インポート機能を利用した他のコンテンツタイプへ貼り付けてください。" + +#: modules/cck/modules/content_copy/content_copy.module:154;38 +msgid "Export" +msgstr "エクスポート" + +#: modules/cck/modules/content_copy/content_copy.module:227 +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "このフォームでは、他のコンテンツタイプやデータベースからエクスポートされたフィールド定義をインポートします。<br />同一のコンテンツタイプ内では重複するフィールドを作成できないため、インポートされたフィールドのうち、選択したコンテンツタイプ内にまだ作成されていないフィールドのみが追加されるということに注意してください。" + +#: modules/cck/modules/content_copy/content_copy.module:230 +msgid "<Create>" +msgstr "<新規作成>" + +#: modules/cck/modules/content_copy/content_copy.module:232 +msgid "Content type" +msgstr "コンテンツタイプ" + +#: modules/cck/modules/content_copy/content_copy.module:233 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "フィールドをインポートするコンテンツタイプを選択してください。<br /><新規作成> を選択した場合、フィールドを含む新しいコンテンツタイプが作成されます。" + +#: modules/cck/modules/content_copy/content_copy.module:238 +msgid "Import data" +msgstr "インポートデータ" + +#: modules/cck/modules/content_copy/content_copy.module:240 +msgid "Paste the text created by a content export into this field." +msgstr "エクスポートされた内容をこのフィールド内にコピーしてください。" + +#: modules/cck/modules/content_copy/content_copy.module:244;46 +msgid "Import" +msgstr "インポート" + +#: modules/cck/modules/content_copy/content_copy.module:270 +msgid "The import data is not valid import text." +msgstr "入力したインポートデータは有効なインポートテキストではありません。" + +#: modules/cck/modules/content_copy/content_copy.module:318 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "インポートした内容を動作させるためには次のモジュールを有効にする必要があります。: %modules" + +#: modules/cck/modules/content_copy/content_copy.module:324;338 +msgid "<create>" +msgstr "<新規作成>" + +#: modules/cck/modules/content_copy/content_copy.module:326 +msgid "The content type %type already exists in this database." +msgstr "%type コンテンツタイプは既にデータベースに存在しています。" + +#: modules/cck/modules/content_copy/content_copy.module:333 +msgid "Exiting. No import performed." +msgstr "インポートを終了します。 インポートは実行されませんでした。" + +#: modules/cck/modules/content_copy/content_copy.module:355 +msgid "An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "%type コンテンツタイプの追加でエラーが発生しました。<br />詳細については、表示されたエラーを確認してください。" + +#: modules/cck/modules/content_copy/content_copy.module:380 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "インポートした %field_label (%field_name) フィールドは %type 内に既に存在しているため追加されませんでした。" + +#: modules/cck/modules/content_copy/content_copy.module:389 +msgid "The field %field_label (%field_name) was added to the content type %type." +msgstr "%field_label (%field_name) フィールドが %type コンテンツタイプに追加されました。" + +#: modules/cck/modules/content_copy/content_copy.module:503 +msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'." +msgstr "%field_name フィールドの 'フィールドの表示' データのエクスポート時にエラーが発生しました。<br />データベースエラー: '%db_err'" + +#: modules/cck/modules/content_copy/content_copy.module:0 +msgid "content_copy" +msgstr "コンテンツコピー" + +#: modules/cck/includes/content.admin.inc:15;552;804 +msgid "Field name" +msgstr "フィールド名" + +#: modules/cck/includes/content.admin.inc:15;582;593;810 +msgid "Field type" +msgstr "フィールドタイプ" + +#: modules/cck/includes/content.admin.inc:15 +msgid "Used in" +msgstr "利用" + +#: modules/cck/includes/content.admin.inc:38 +msgid "No fields have been defined for any content type yet." +msgstr "すべてのコンテンツタイプでフィールドが定義されていません。" + +#: modules/cck/includes/content.admin.inc:63;242 +msgid "There are no fields configured for this content type. You can !link." +msgstr "このコンテンツタイプで設定されたフィールドはありません。 !link を行うことができます。" + +#: modules/cck/includes/content.admin.inc:64;243 +msgid "Add a new field" +msgstr "新しいフィールドの追加" + +#: modules/cck/includes/content.admin.inc:88 +msgid "To change the order of a field, grab a drag-and-drop handle under the Label column and drag the field to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the Save button at the bottom of the page." +msgstr "フィールドの順序を変更するには、ラベル部分にあるドラッグ&ドロップハンドルをつかんでリスト内の新しい場所までドラッグしてください。(ハンドルアイコンの上でマウスボタンを押したままの状態にすることでハンドルをつかむことができます。) ページ下部の保存ボタンをクリックするまでは、行った変更が保存されないことに注意してください。" + +#: modules/cck/includes/content.admin.inc:98;114 +msgid "Configure" +msgstr "設定" + +#: modules/cck/includes/content.admin.inc:163 +msgid "Name" +msgstr "名前" + +#: modules/cck/includes/content.admin.inc:163 +msgid "Type" +msgstr "タイプ" + +#: modules/cck/includes/content.admin.inc:163 +msgid "Weight" +msgstr "ウェイト" + +#: modules/cck/includes/content.admin.inc:163 +msgid "Operations" +msgstr "操作" + +#: modules/cck/includes/content.admin.inc:270;311 +msgid "Above" +msgstr "上部" + +#: modules/cck/includes/content.admin.inc:271 +msgid "Inline" +msgstr "インライン" + +#: modules/cck/includes/content.admin.inc:272;297;312;320 +msgid "<Hidden>" +msgstr "<非表示>" + +#: modules/cck/includes/content.admin.inc:315 +msgid "no styling" +msgstr "スタイルなし" + +#: modules/cck/includes/content.admin.inc:316 +msgid "simple" +msgstr "シンプル" + +#: modules/cck/includes/content.admin.inc:317 +msgid "fieldset" +msgstr "フィールドセット" + +#: modules/cck/includes/content.admin.inc:318 +msgid "fieldset - collapsible" +msgstr "フィールドセット - 折りたたみ(開)" + +#: modules/cck/includes/content.admin.inc:319 +msgid "fieldset - collapsed" +msgstr "フィールドセット - 折りたたみ(閉)" + +#: modules/cck/includes/content.admin.inc:364 +msgid "Field" +msgstr "フィールド" + +#: modules/cck/includes/content.admin.inc:411 +msgid "Your settings have been saved." +msgstr "設定が保存されました。" + +#: modules/cck/includes/content.admin.inc:428 +msgid "No field modules are enabled. You need to <a href=\"!modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "フィールドを追加するためのモジュールが有効になっていません。 新しいフィールドを追加する前に、Text モジュール等の <a href=\"!modules_url\">モジュールを有効化</a> する必要があります。" + +#: modules/cck/includes/content.admin.inc:470 +msgid "Add existing field" +msgstr "既存のフィールドを追加" + +#: modules/cck/includes/content.admin.inc:479 +#: modules/cck/content.module:173 +msgid "Add field" +msgstr "フィールドの追加" + +#: modules/cck/includes/content.admin.inc:497 +msgid "Added field %label." +msgstr "%label フィールドを追加しました。" + +#: modules/cck/includes/content.admin.inc:500 +msgid "There was a problem adding field %label." +msgstr "%label フィールドの追加中に問題が発生しました。" + +#: modules/cck/includes/content.admin.inc:540 +msgid "Create new field" +msgstr "フィールドの新規作成" + +#: modules/cck/includes/content.admin.inc:547 +msgid "Edit basic information" +msgstr "基本情報の編集" + +#: modules/cck/includes/content.admin.inc:556 +msgid "The machine-readable name of the field." +msgstr "コンピュータが扱うことのできる、このフィールドの名前を入力してください。" + +#: modules/cck/includes/content.admin.inc:560 +msgid " This name cannot be changed." +msgstr " この名前は変更できません。" + +#: modules/cck/includes/content.admin.inc:568 +msgid " This name cannot be changed later! The name will be prefixed with 'field_' and can include lowercase unaccented letters, numbers, and underscores. The length of the name, including the prefix, is limited to no more than 32 letters." +msgstr " この名前は後から変更することができません! フィールド名には 'field_' という接頭語が追加されます。 名前に使用できる文字はアクセント記号のない英小文字、数字、アンダースコア(_)のみです。 フィールド名は接頭語を含んで 32 文字以内にしてください。" + +#: modules/cck/includes/content.admin.inc:576 +msgid "A human-readable name to be used as the label for this field in the %type content type." +msgstr "人が読むことのできる、このフィールドの名前を入力してください。 この名前は %type コンテンツタイプのラベルとして使用されます。" + +#: modules/cck/includes/content.admin.inc:586 +msgid "The type of data you would like to store in the database with this field." +msgstr "データベースに保存する、このフィールドのデータ型を選択してください。" + +#: modules/cck/includes/content.admin.inc:596 +msgid "The type of data you would like to store in the database with this field. This option cannot be changed." +msgstr "データベースに保存する、このフィールドのデータ型を選択してください。 このオプションは変更できません。" + +#: modules/cck/includes/content.admin.inc:601;817 +msgid "Widget type" +msgstr "ウィジェットタイプ" + +#: modules/cck/includes/content.admin.inc:605 +msgid "The type of form element you would like to present to the user when creating this field in the %type content type." +msgstr "使用したいフォームエレメントのタイプを選択してください。 選択したウィジェットタイプは %type コンテンツタイプのフィールドに適用されます。" + +#: modules/cck/includes/content.admin.inc:619 +msgid "Continue" +msgstr "継続" + +#: modules/cck/includes/content.admin.inc:640 +msgid "The field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "フィールド名 %field_name は無効です。 フィールド名に使用できる文字は、アクセント記号のない英小文字、数字、アンダースコア(_)のみです。" + +#: modules/cck/includes/content.admin.inc:644 +msgid "The field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix." +msgstr "フィールド名 %field_name は最大文字数を超えています。 フィールド名は 'field_' 接頭語を含む 32 文字までに制限されています。" + +#: modules/cck/includes/content.admin.inc:648 +msgid "The field name %field_name already exists." +msgstr "フィールド名 %field_name は既に存在します。" + +#: modules/cck/includes/content.admin.inc:652 +msgid "The name 'field_instance' is a reserved name." +msgstr "フィールド名 'field_instance' は予約語です。" + +#: modules/cck/includes/content.admin.inc:684 +msgid "Created field %label." +msgstr "%label フィールドを作成しました。" + +#: modules/cck/includes/content.admin.inc:688 +msgid "There was a problem creating field %label." +msgstr "%label フィールドの作成中に問題が発生しました。" + +#: modules/cck/includes/content.admin.inc:697 +msgid "Update field %label." +msgstr "%label フィールドをアップデートしました。" + +#: modules/cck/includes/content.admin.inc:701 +msgid "There was a problem updating field %label." +msgstr "%label フィールドの更新中に問題が発生しました。" + +#: modules/cck/includes/content.admin.inc:729 +msgid "Are you sure you want to remove the field %field?" +msgstr "本当に、%field フィールドを取り外してよろしいですか?" + +#: modules/cck/includes/content.admin.inc:732 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "このフィールドに含まれるすべての内容を削除します。 この操作は元に戻すことができません。" + +#: modules/cck/includes/content.admin.inc:751 +msgid "Removed field %field from %type." +msgstr "%type から %field フィールドを取り外しました。" + +#: modules/cck/includes/content.admin.inc:756 +msgid "There was a problem deleting %field from %type." +msgstr "%label フィールドの削除中に問題が発生しました。" + +#: modules/cck/includes/content.admin.inc:782;824 +msgid "Change basic information" +msgstr "基本情報の変更" + +#: modules/cck/includes/content.admin.inc:794 +msgid "%type basic information" +msgstr "%type 基本情報" + +#: modules/cck/includes/content.admin.inc:831 +msgid "%type settings" +msgstr "%type 設定" + +#: modules/cck/includes/content.admin.inc:832 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "これらの設定は %type コンテンツタイプの %field フィールドのみに適用されます。" + +#: modules/cck/includes/content.admin.inc:849 +msgid "Instructions to present to the user below this field on the editing form." +msgstr "コンテンツの追加・編集フォームで、このフィールドの下部に表示するユーザへの説明です。" + +#: modules/cck/includes/content.admin.inc:857 +msgid "Default value" +msgstr "デフォルト値" + +#: modules/cck/includes/content.admin.inc:901 +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format :<pre>!sample</pre>Using !link_devel's 'devel load' tab on a %type content page might help you figure out the expected format." +msgstr "PHP に精通した方専用: デフォルト値として返す PHP コードを <?php ?> を含めずに記入してください。 このフィールドが入力されている場合、このコードによって返される値は上記で指定したすべての値を上書きします。<br />期待されるフォーマット: <pre>!sample</pre>%type コンテンツページで !link_devel の 'Devel ロード' タブを使用することが、予想フォーマットの理解を助けるかもしれません。" + +#: modules/cck/includes/content.admin.inc:910 +msgid "Global settings" +msgstr "全般の設定" + +#: modules/cck/includes/content.admin.inc:911 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "これらの設定は %field フィールドが表示されるすべてのコンテンツタイプで適用されます。" + +#: modules/cck/includes/content.admin.inc:915 +msgid "Required" +msgstr "必須" + +#: modules/cck/includes/content.admin.inc:920 +msgid "Number of values" +msgstr "値の数" + +#: modules/cck/includes/content.admin.inc:921 +msgid "Unlimited" +msgstr "無制限" + +#: modules/cck/includes/content.admin.inc:923 +msgid "Select a specific number of values for this field, or 'Unlimited' to provide an 'Add more' button so the users can add as many values as they like." +msgstr "このフィールドが持つことのできる値の数を選択してください。 'アイテムの追加' ボタンを表示し自由に多くの値を追加できるようにしたい場合は、'無制限' を選択してください。" + +#: modules/cck/includes/content.admin.inc:923 +msgid "Warning! Changing this setting after data has been created could result in the loss of data!" +msgstr "警告!データ入力後にこの設定を変更すると、データの損失を招く可能性があります!" + +#: modules/cck/includes/content.admin.inc:938 +msgid "Save field settings" +msgstr "フィールド設定の保存" + +#: modules/cck/includes/content.admin.inc:1031 +msgid "The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value" +msgstr "デフォルト値として返される PHP コードの値に誤った値が返されました。<br />期待されるフォーマット: <pre>!sample</pre>返された値: @value" + +#: modules/cck/includes/content.admin.inc:1068 +msgid "The default value PHP code created @value which is invalid." +msgstr "デフォルト値として返された PHP コードの値 @value は無効です。" + +#: modules/cck/includes/content.admin.inc:1072 +msgid "The default value is invalid." +msgstr "デフォルト値は無効です。" + +#: modules/cck/includes/content.admin.inc:1090 +msgid "Saved field %label." +msgstr "%label フィールドを保存しました。" + +#: modules/cck/includes/content.admin.inc:1398 +msgid "Processing" +msgstr "処理中" + +#: modules/cck/includes/content.admin.inc:1399 +msgid "The update has encountered an error." +msgstr "アップデートはエラーに遭遇しました。" + +#: modules/cck/includes/content.admin.inc:1413 +msgid "The database has been altered and data has been migrated or deleted." +msgstr "データベースが変更され、データは移動または削除されました。" + +#: modules/cck/includes/content.admin.inc:1416 +msgid "An error occurred and database alteration did not complete." +msgstr "エラーが発生したため、データベースの変更は完了しませんでした。" + +#: modules/cck/includes/content.admin.inc:1519 +msgid "Processing %title" +msgstr "%title を処理しています。" + +#: modules/cck/includes/content.admin.inc:1417 +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "1 アイテムが正常に処理されました:" +msgstr[1] "@count アイテムが正常に処理されました:" + +#: modules/cck/includes/content.crud.inc:563;600 +#: modules/cck/content.module:568;575;0 +msgid "content" +msgstr "コンテンツ" + +#: modules/cck/includes/content.crud.inc:563 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "コンテンツフィールドテーブル %old_name の名前が %new_name に変更され、フィールドのインスタンスもアップデートされました。" + +#: modules/cck/includes/content.crud.inc:600 +msgid "The content fields table %name has been deleted." +msgstr "コンテンツフィールドテーブル %name が削除されました。" + +#: modules/cck/includes/content.node_form.inc:195 +msgid "Add another !field value" +msgstr "!field フィールドの値の追加" + +#: modules/cck/includes/content.node_form.inc:196 +msgid "If the amount of boxes above isn't enough, click here to add more items." +msgstr "上の内容量が不足した場合は、ここをクリックしてアイテムを追加できます。" + +#: modules/cck/includes/content.token.inc:60 +msgid "Referenced node ID" +msgstr "参照ノード ID" + +#: modules/cck/includes/content.token.inc:61 +msgid "Referenced node title" +msgstr "参照ノードタイトル" + +#: modules/cck/includes/content.token.inc:62 +msgid "Formatted HTML link to the node" +msgstr "HTML フォーマットのノードへのリンク" + +#: modules/cck/includes/content.token.inc:86 +msgid "Raw number value" +msgstr "数値(RAW データ)" + +#: modules/cck/includes/content.token.inc:87 +msgid "Formatted number value" +msgstr "フォーマットされた数値" + +#: modules/cck/includes/content.token.inc:110 +msgid "Raw, unfiltered text" +msgstr "フィルタを通していないテキスト(RAW データ)" + +#: modules/cck/includes/content.token.inc:111 +msgid "Formatted and filtered text" +msgstr "フォーマットおよびフィルタされたテキスト" + +#: modules/cck/includes/content.token.inc:133 +msgid "Referenced user ID" +msgstr "参照ユーザの ID" + +#: modules/cck/includes/content.token.inc:134 +msgid "Referenced user name" +msgstr "参照ユーザの名前" + +#: modules/cck/includes/content.token.inc:135 +msgid "Formatted HTML link to referenced user" +msgstr "HTML フォーマットの参照ユーザへのリンク" + +#: modules/cck/includes/content.views.inc:57;94 +#: modules/cck/content.info:0 +msgid "Content" +msgstr "コンテンツ" + +#: modules/cck/includes/content.views.inc:96 +msgid "Appears in : @types" +msgstr "発行: @types" + +#: modules/cck/includes/content.views.inc:294 +msgid "Format" +msgstr "フォーマット" + +#: modules/cck/includes/content.views.inc:375 +msgid "Group multiple values" +msgstr "値をグループ化する" + +#: modules/cck/includes/content.views.inc:382 +msgid "Show" +msgstr "表示" + +#: modules/cck/includes/content.views.inc:383 +msgid " values," +msgstr " 個の値、" + +#: modules/cck/includes/content.views.inc:390 +msgid "Starting from" +msgstr "開始する値" + +#: modules/cck/includes/content.views.inc:394 +msgid "Start from last values" +msgstr "最後の値から開始する" + +#: modules/cck/examples/example_field.php:484 +msgid "Text area" +msgstr "テキストエリア" + +#: modules/cck/content.info:0 +msgid "Allows administrators to define new content types." +msgstr "管理者が新しいコンテンツタイプを定義できるようにします。" + +#: modules/cck/content.module:25 +msgid "The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default \"Title\" and \"Body\" may be added. CCK features are accessible through tabs on the <a href=\"@content-types\">content types administration page</a>. (See the <a href=\"@node-help\">node module help page</a> for more information about content types.)" +msgstr "コンテンツモジュールは、Content Construction Kit (CCK) の必須のコンポーネントであり、管理者がコンテンツタイプにカスタムフィールドを追加するための機能を提供します。 Drupal では、コンテンツの追加および編集時に、コンテンツの入力フィールドにタイトルや説明を表示することによって、投稿するコンテンツに異なる特徴を定義するために、コンテンツタイプが使用されます。 コンテンツモジュール(および CCK に含まれる他のヘルパーモジュール)を使用して、デフォルトの \"タイトル\" や \"本文\" 以外のカスタムフィールドを追加することができます。 CCK の機能へは、<a href=\"@content-types\">コンテンツタイプの管理ページ</a> のタブメニューからアクセスできます。 (コンテンツタイプについての詳細は <a href=\"@node-help\">Node モジュールのヘルプページ</a> を参照してください。 )" + +#: modules/cck/content.module:26 +msgid "When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a \"person\" may have multiple e-mail addresses) or a single value (i.e., an \"employee\" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules." +msgstr "カスタムフィールドをコンテンツタイプに追加する場合、追加するフィールドのタイプ(テキスト、数字、他のオブジェクトの参照の何れか)と、フィールドの表示スタイル(テキストフィールド、テキストエリア、選択ボックス、チェックボックス、ラジオボタン、オートコンプリートフィールドの何れか)を決定します。 フィールドは複数の値(例: \"個人\" は複数の E-mail アドレスを持つかもしれません)もしくは、ひとつの値(例: \"従業員\" は固有の社員番号を持ちます)を持つことができます。 フィールドの追加や編集を行うと、CCK は必要に応じて自動的にデータベースの構造を調節します。 また CCK は他にも、カスタムデータのためのインテリジェント・キャッシング、コンテンツタイプ定義のためのインポート/エクスポート機能、他の寄与モジュールの統合などを含む多くの特徴も提供します。" + +#: modules/cck/content.module:27 +msgid "Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href=\"@modules\">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:" +msgstr "カスタムフィールドのタイプは CCK に含まれるオプションモジュールから、それぞれ別のタイプとして提供します。 <a href=\"@modules\">モジュールページ</a> から CCK コンポーネントの有効/無効を切り替えることができます。 CCK のデフォルトインストールは次を含みます。:" + +#: modules/cck/content.module:29 +msgid "<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available." +msgstr "<storng>数字</storng>は、数値形式のフィールドタイプとして、整数、小数、浮動小数点のデータ型フィールドを追加します。 入力値として、使用する値のリストを定義するか、もしくは、入力可能な値の範囲を指定することができます。 数値データのデータの表示に関して、多様な共通フォーマットを利用できます。" + +#: modules/cck/content.module:30 +msgid "<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values." +msgstr "<storng>テキスト</storng>は、テキストフィールドタイプのフィールドを追加します。 テキストフィールドにはプレーンテキストのみを含むことができますが、オプションとして、安全なリッチテキストの入力のために Drupal の入力書式を使用することもできます。 テキストの入力フィールドには、一般的なテキストフィールドのような 1行の入力フォームやテキストエリアのような複数行の入力フォームが使用できます。 また、入力内容をコントロールしたい場合などのために、選択ボックス、チェックボックス、ラジオボタンも使用できます。 必要に応じて、入力値に使用する値のリストを設定することも可能です。" + +#: modules/cck/content.module:31 +msgid "<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple \"employee\" nodes may contain a <em>nodereference</em> field linking to an \"employer\" node)." +msgstr "<storng>ノード参照</storng>は、サイト内の他のノードを参照するためのフィールドを追加します。 <storng>ノード参照</storng>フィールドを使うことで、2つの異なるコンテンツタイプ間での複雑な親子関係を簡単に作成することができます。 例えば、複数の \"従業員\" ノードに 1つの \"雇用主\" ノードを参照する<storng>ノード参照</storng>フィールドを持たせることができます。" + +#: modules/cck/content.module:32 +msgid "<em>userreference</em>, which creates custom references to your sites' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site's users and posts. To track user involvement in a post beyond Drupal's standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named \"Edited by\" to a content type to store a link to an editor's user account page." +msgstr "<storng>ユーザ参照</storng>は、サイト内のユーザアカウントを参照するためのフィールドを追加します。 <storng>ユーザ参照</storng>フィールドを使うことで、サイトユーザと投稿間での複雑な親子関係を作成することができます。 例えば、\"編集者\" という<storng>ユーザ参照</storng>フィールドによって、Drupal 標準の<storng>投稿者</storng>フィールドを使用するだけでは軌跡に表示されないノードへのリンクを、それぞれの編集者のユーザアカウントページに追加することができます。" + +#: modules/cck/content.module:33 +msgid "<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module." +msgstr "<storng>フィールドグループ</storng>は、関連するフィールドをグループ化するための折りたたみ可能なフィールドセットを追加します。 フィールドセットのデフォルトの状態として、開いている状態または閉じている状態のどちらかを選択できます。 フィールドセットおよびフィールドセット内のフィールドの順序は、コンテンツモジュールが提供するドラッグ&ドロップインターフェイスによって管理されます。" + +#: modules/cck/content.module:35 +msgid "For more information, see the online handbook entry for <a href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK project page</a>." +msgstr "詳細については、Drupal handbook の <a href=\"@handbook-cck\">CCK</a> ページまたは <a href=\"@project-cck\">CCK プロジェクト</a>ページで確認できます。" + +#: modules/cck/content.module:41 +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "このコンテンツタイプで作成されたノードが要約ページや全文ページとして表示されたときの、フィールドやラベルの表示方法について設定します。" + +#: modules/cck/content.module:44 +msgid "Configure how this content type's fields should be displayed when it's rendered in the following contexts." +msgstr "このコンテンツタイプのフィールドについて、以下の場面で表示される時の表示方法を設定してください。" + +#: modules/cck/content.module:48 +msgid "Control the order of fields in the input form." +msgstr "入力フォームに表示するフィールドの順序をコントロールします。" + +#: modules/cck/content.module:479 +msgid "This field is required." +msgstr "このフィールドの入力は必須です。" + +#: modules/cck/content.module:483 +msgid "!title: !required" +msgstr "!title: !required" + +#: modules/cck/content.module:486 +msgid "Order" +msgstr "並べ替え順" + +#: modules/cck/content.module:516 +msgid "Add another item" +msgstr "アイテムの追加" + +#: modules/cck/content.module:1616 +msgid "RSS Item" +msgstr "RSS アイテム" + +#: modules/cck/content.module:1618 +msgid "Search Index" +msgstr "検索インデックス" + +#: modules/cck/content.module:1619 +msgid "Search Result" +msgstr "検索結果" + +#: modules/cck/content.module:1957 +msgid "Language" +msgstr "言語" + +#: modules/cck/content.module:1960 +msgid "Taxonomy" +msgstr "タクソノミー" + +#: modules/cck/content.module:1963 +msgid "File attachments" +msgstr "ファイルの添付" + +#: modules/cck/content.module:568 +msgid "Updating field type %type with module %module." +msgstr "%module モジュールによって %type タイプフィールドが更新されました。" + +#: modules/cck/content.module:575 +msgid "Updating widget type %type with module %module." +msgstr "%module モジュールによって %type タイプウィジェットが更新されました。" + +#: modules/cck/content.module:142 +msgid "Manage fields" +msgstr "フィールドの管理" + +#: modules/cck/content.module:151 +msgid "Display fields" +msgstr "フィールドの表示" + +#: modules/cck/content.module:160 +msgid "General" +msgstr "全般" + +#: modules/cck/content.module:166 +msgid "Advanced" +msgstr "高度な設定" + +#: modules/cck/content.module:194 +msgid "Remove field" +msgstr "フィールドの取り外し" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/nl.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/nl.po new file mode 100644 index 0000000000000000000000000000000000000000..d01dcc9f446958e2c8ad160e8854093896dad1be --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/nl.po @@ -0,0 +1,406 @@ +# $Id$ +# translation of nl.po to +# translation of cck.po to +# LANGUAGE translation of Drupal (cck) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 JonBob +# text.module,v 1.32.2.2 2006/05/03 12:56:52 JonBob +# number.module,v 1.27.2.2 2006/05/03 12:56:52 JonBob +# content_admin.inc,v 1.12.2.2 2006/05/03 12:56:52 JonBob +# content.module,v 1.56.2.3 2006/05/03 12:56:52 JonBob +# nodereference.module,v 1.25.2.3 2006/05/05 14:22:41 JonBob +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 JonBob +# userreference.module,v 1.22.2.3 2006/05/05 14:22:41 JonBob +# content_admin.inc,v 1.12.2.2 2006/05/03 12:56:52 JonBob +# +# Bèr Kessels <ber@webschuur.com>, 2006. +msgid "" +msgstr "" +"Project-Id-Version: nl\n" +"POT-Creation-Date: 2006-05-20 04:11+0100\n" +"PO-Revision-Date: 2006-06-12 13:24+0200\n" +"Last-Translator: Bèr Kessels <ber@webschuur.com>\n" +"Language-Team: <nl@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: KBabel 1.11.2\n" + +#: field.php:77 text.module:44 +msgid "Maximum length" +msgstr "Maximum lengte" + +#: field.php:80 text.module:47 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "" + +#: field.php:102 number.module:82 text.module:80 +msgid "is equal to" +msgstr "is gelijk aan" + +#: field.php:103 number.module:83 text.module:81 +msgid "is not equal to" +msgstr "is niet gelijk aan" + +#: field.php:104 text.module:82 +msgid "matches the pattern" +msgstr "komt overeen met patroon" + +#: field.php:180;190 number.module:119 text.module:107 +msgid "Illegal value for %name." +msgstr "" + +#: field.php:265 text.module:159 +msgid "Rows" +msgstr "Rijen" + +#: field.php:273 text.module:167 +msgid "\"Rows\" must be a positive integer." +msgstr "\"Rijen\" moet een positief geheel getal zijn." + +#: content_admin.inc:24 content.module:128 +msgid "edit" +msgstr "bewerken" + +#: content_admin.inc:25 content.module:119 +msgid "duplicate" +msgstr "duplicaat" + +#: content_admin.inc:26 content.module:111 +msgid "delete" +msgstr "verwijderen" + +#: number.module:48 text.module:51 +msgid "Allowed values" +msgstr "" + +#: number.module:52 text.module:55 +msgid "The possible values this field can contain. Any other values will result in an error. Enter one value per line." +msgstr "" + +#: content.module:18 +msgid "Allows administrators to define new content types." +msgstr "" + +#: content.module:61 +msgid "content types" +msgstr "inhoudstypen" + +#: content.module:67 +msgid "list" +msgstr "lijst" + +#: content.module:73 +msgid "add content type" +msgstr "" + +#: content.module:80 +msgid "fields" +msgstr "velden" + +#: content.module:135 +msgid "manage fields" +msgstr "" + +#: content.module:144 +msgid "add field" +msgstr "veld toevoegen" + +#: content.module:164 +msgid "remove field" +msgstr "veld verwijderen" + +#: content.module:0 +msgid "content" +msgstr "inhoud" + +#: nodereference.module:15 +msgid "Defines a field type for referencing one node from another. <em>Note: Requires content.module.</em>" +msgstr "" + +#: nodereference.module:26 +msgid "node reference autocomplete" +msgstr "node verwijzing auto-aanvullen" + +#: nodereference.module:51 +msgid "Content types that can be referenced" +msgstr "" + +#: nodereference.module:204 +msgid "No post with that title exists." +msgstr "" + +#: nodereference.module:0 +msgid "nodereference" +msgstr "" + +#: number.module:15 +msgid "Defines numeric field types. <em>Note: Requires content.module.</em>" +msgstr "" + +#: number.module:38 +msgid "Minimum" +msgstr "" + +#: number.module:43 +msgid "Maximum" +msgstr "" + +#: number.module:58 +msgid "\"Minimum\" must be a number." +msgstr "" + +#: number.module:61 +msgid "\"Maximum\" must be a number." +msgstr "" + +#: number.module:113 +msgid "The value of %name may be no smaller than %min." +msgstr "" + +#: number.module:116 +msgid "The value of %name may be no larger than %max." +msgstr "" + +#: number.module:0 +msgid "number" +msgstr "getal" + +#: optionwidgets.module:15 +msgid "Defines selection, check box and radio button widgets for text and numeric fields. <em>Note: Requires content.module, text.module and number.module.</em>" +msgstr "" + +#: optionwidgets.module:0 +msgid "optionwidgets" +msgstr "" + +#: text.module:15 +msgid "Defines simple text field types. <em>Note: Requires content.module.</em>" +msgstr "" + +#: text.module:35 +msgid "Plain text" +msgstr "Platte tekst" + +#: text.module:35 +msgid "Filtered text (user selects input format)" +msgstr "Gefilterede tekst (gebruiker geeft invoerformaat op)" + +#: text.module:38 +msgid "Text processing" +msgstr "" + +#: text.module:0 +msgid "text" +msgstr "tekst" + +#: userreference.module:15 +msgid "Defines a field type for referencing a user from a node. <em>Note: Requires content.module.</em>" +msgstr "" + +#: userreference.module:176 +msgid "Invalid user name." +msgstr "ongeldige gebruikersnaam." + +#: userreference.module:0 +msgid "userreference" +msgstr "" + +#: content_admin.inc:16;87;235;314;544 +msgid "Label" +msgstr "" + +#: content_admin.inc:16;42;235 +msgid "Name" +msgstr "Naam" + +#: content_admin.inc:16;94 +msgid "Description" +msgstr "Beschrijving" + +#: content_admin.inc:16;235 +msgid "Operations" +msgstr "Handelingen" + +#: content_admin.inc:42;235 +msgid "Type" +msgstr "Type" + +#: content_admin.inc:42 +msgid "Content types" +msgstr "Inoudstypen" + +#: content_admin.inc:90 +msgid "The human-readable name of this content type." +msgstr "De leesbare naam van dit inhoudstype." + +#: content_admin.inc:98 +msgid "A brief description of the content type." +msgstr "" + +#: content_admin.inc:102;560 +msgid "Help text" +msgstr "Helptekst" + +#: content_admin.inc:106 +msgid "Instructions to present to the user when adding new content of this type." +msgstr "" + +#: content_admin.inc:110 +msgid "Title field label" +msgstr "Titel veld label" + +#: content_admin.inc:113 +msgid "The label for the title field." +msgstr "" + +#: content_admin.inc:118 +msgid "Save content type" +msgstr "Indienen inhoud type" + +#: content_admin.inc:182 +msgid "Saved content type %type." +msgstr "" + +#: content_admin.inc:199 +msgid "Are you sure you want to delete the content type %type?" +msgstr "" + +#: content_admin.inc:199 +msgid "If you have any content left in this content type, it will be permanently deleted. This action cannot be undone." +msgstr "" + +#: content_admin.inc:199 +msgid "Delete" +msgstr "Verwijderen" + +#: content_admin.inc:199;462 +msgid "Cancel" +msgstr "Annuleren" + +#: content_admin.inc:220 +msgid "Deleted content type %type." +msgstr "Verwijderd inhoud type %type." + +#: content_admin.inc:250 +msgid "configure" +msgstr "configureren" + +#: content_admin.inc:251 +msgid "remove" +msgstr "verwijderen" + +#: content_admin.inc:281 +msgid "Add existing field" +msgstr "" + +#: content_admin.inc:290 +msgid "Add field" +msgstr "Veld toeveogen" + +#: content_admin.inc:311 +msgid "Create new field" +msgstr "Nieuw veld aanmaken" + +#: content_admin.inc:317 +msgid "The human-readable name of this field." +msgstr "" + +#: content_admin.inc:322 +msgid "Field type" +msgstr "Veldtype" + +#: content_admin.inc:330 +msgid "Create field" +msgstr "" + +#: content_admin.inc:339 +msgid "No field modules are enabled. You need to <a href=\"%modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "" + +#: content_admin.inc:396 +msgid "Added field %label." +msgstr "" + +#: content_admin.inc:441 +msgid "Created field %label." +msgstr "" + +#: content_admin.inc:462 +msgid "Are you sure you want to remove the field %field?" +msgstr "" + +#: content_admin.inc:462 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "" + +#: content_admin.inc:462 +msgid "Remove" +msgstr "" + +#: content_admin.inc:479 +msgid "Removed field %field from %type." +msgstr "" + +#: content_admin.inc:498 +msgid "The field %field no longer exists in any content type, so it was deleted." +msgstr "" + +#: content_admin.inc:522 +msgid "Widget settings" +msgstr "Widget instellingen" + +#: content_admin.inc:523 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "" + +#: content_admin.inc:537 +msgid "Widget" +msgstr "" + +#: content_admin.inc:550 +msgid "Weight" +msgstr "Gewicht" + +#: content_admin.inc:552 +msgid "In the node editing form, the heavier fields will sink and the lighter fields will be positioned nearer the top." +msgstr "" + +#: content_admin.inc:563 +msgid "Instructions to present to the user below this field on the editing form." +msgstr "" + +#: content_admin.inc:569 +msgid "Data settings" +msgstr "Data instellingen" + +#: content_admin.inc:570 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "" + +#: content_admin.inc:574 +msgid "Required" +msgstr "Vereist" + +#: content_admin.inc:579 +msgid "Multiple values" +msgstr "Meerdere waarden" + +#: content_admin.inc:590 +msgid "Save field settings" +msgstr "Veldinstellingen indienen" + +#: content_admin.inc:665 +msgid "Saved field %field." +msgstr "" + +#: content_admin.inc:896;985 +msgid "No PostgreSQL mapping found for %type data type." +msgstr "" + +#: content_admin.inc:896;985 +msgid "database" +msgstr "database" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/pt-br.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/pt-br.po new file mode 100644 index 0000000000000000000000000000000000000000..9d7bbc03bd2bb5eacf73d4f0296cb077c9aca8d6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/pt-br.po @@ -0,0 +1,1523 @@ +# Portuguese, Brazil translation of Content Construction Kit (CCK) (6.x-2.6) +# Copyright (c) 2010 by the Portuguese, Brazil translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Content Construction Kit (CCK) (6.x-2.6)\n" +"POT-Creation-Date: 2010-05-28 15:21+0000\n" +"PO-Revision-Date: 2010-05-28 15:18+0000\n" +"Language-Team: Portuguese, Brazil\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +msgid "CCK" +msgstr "CCK" +msgid "delete" +msgstr "apagar" +msgid "Prefix" +msgstr "Prefixo" +msgid "Suffix" +msgstr "Sufixo" +msgid "Operations" +msgstr "Operações" +msgid "Content" +msgstr "Conteúdo" +msgid "content" +msgstr "conteúdo" +msgid "Type" +msgstr "Tipo" +msgid "Cancel" +msgstr "Cancelar" +msgid "Remove" +msgstr "Remover" +msgid "Description" +msgstr "Descrição" +msgid "Language" +msgstr "Língua" +msgid "Block title" +msgstr "Título do bloco" +msgid "Taxonomy" +msgstr "Taxonomia" +msgid "Content types" +msgstr "Tipos de conteúdo" +msgid "Search" +msgstr "Buscar" +msgid "None" +msgstr "Nenhum" +msgid "Display settings" +msgstr "Opções de exibição" +msgid "This action cannot be undone." +msgstr "Esta operação não poderá ser desfeita." +msgid "Number" +msgstr "Número" +msgid "- None -" +msgstr "- Nenhum -" +msgid "Weight" +msgstr "Peso" +msgid "Help text" +msgstr "Texto de ajuda" +msgid "Types" +msgstr "Tipos" +msgid "Required" +msgstr "Obrigatório" +msgid "none" +msgstr "nenhum" +msgid "Name" +msgstr "Nome" +msgid "edit" +msgstr "editar" +msgid "Import" +msgstr "Importar" +msgid "Book" +msgstr "Livro" +msgid "Export" +msgstr "Exportar" +msgid "Field" +msgstr "Campo" +msgid "Label" +msgstr "Rótulo" +msgid "Save" +msgstr "Salvar" +msgid "Default" +msgstr "Padrão" +msgid "Add" +msgstr "Adicionar" +msgid "Format" +msgstr "Formato" +msgid "Teaser" +msgstr "Chamada" +msgid "Text" +msgstr "Texto" +msgid "Content type" +msgstr "Tipo de conteúdo" +msgid "Continue" +msgstr "Continuar" +msgid "Configure" +msgstr "Configurar" +msgid "Node" +msgstr "Node" +msgid "Include" +msgstr "Incluir" +msgid "Exclude" +msgstr "Excluir" +msgid "All" +msgstr "Tudo" +msgid "View arguments" +msgstr "Argumentos de View" +msgid "RSS" +msgstr "RSS" +msgid "Inline" +msgstr "Mesma linha" +msgid "Delta" +msgstr "Delta" +msgid "Custom" +msgstr "Personalizado" +msgid "Poll choices" +msgstr "Opções da enquete" +msgid "Content field" +msgstr "Campo do conteúdo" +msgid "Field name" +msgstr "Nome do campo" +msgid "Field type" +msgstr "Tipo do campo" +msgid "Global settings" +msgstr "Opções globais" +msgid "Fields" +msgstr "Campos" +msgid "Widget type" +msgstr "Tipo de widget" +msgid "Contains" +msgstr "Contendo" +msgid "N/A" +msgstr "-" +msgid "This field is required." +msgstr "Este campo é obrigatório." +msgid "Maximum" +msgstr "Máximo" +msgid "Scale" +msgstr "Escala" +msgid "Plain text" +msgstr "Texto puro" +msgid "Unlimited" +msgstr "Ilimitado" +msgid "Code" +msgstr "Código" +msgid "Basic" +msgstr "Básico" +msgid "Filtered text (user selects input format)" +msgstr "Texto filtrado (o usuário seleciona o formato de entrada)" +msgid "Text processing" +msgstr "Processamento de texto" +msgid "Maximum length" +msgstr "Comprimento máximo" +msgid "" +"The maximum length of the field in characters. Leave blank for an " +"unlimited size." +msgstr "" +"Número máximo de caracteres no campo. Deixe em branco para não " +"impor um limite." +msgid "Rows" +msgstr "Linhas" +msgid "Existing Views" +msgstr "Views existentes" +msgid "Default Views" +msgstr "Views padrão" +msgid "Empty text" +msgstr "Mensagem \"Não há resultados\"" +msgid "Order" +msgstr "Ordem" +msgid "Integer" +msgstr "Inteiro" +msgid "Edit group" +msgstr "Editar grupo" +msgid "Size of textfield" +msgstr "Tamanho do campo de texto" +msgid "File attachments" +msgstr "Arquivos anexados" +msgid "Token" +msgstr "Token" +msgid "Allowed values list" +msgstr "Lista dos valores permitidos" +msgid "Select list" +msgstr "Lista de seleção" +msgid "Text field" +msgstr "Campo de texto" +msgid "PHP code" +msgstr "Código PHP" +msgid "Display fields" +msgstr "Exibir campos" +msgid "Poll settings" +msgstr "Configurações de enquete" +msgid "Style" +msgstr "Estilo" +msgid "Your settings have been saved." +msgstr "Suas configurações foram salvas." +msgid "Reversed" +msgstr "Revertido" +msgid "%type settings" +msgstr "Configurações de %type" +msgid "Menu settings" +msgstr "Configurações de menu" +msgid "edit " +msgstr "editar " +msgid "<Hidden>" +msgstr "<Oculto>" +msgid "Comment settings" +msgstr "Configurações dos comentários" +msgid "Related content" +msgstr "Conteúdo relacionado" +msgid "Processing" +msgstr "Processando" +msgid "Default value" +msgstr "Valor padrão" +msgid "No content types available." +msgstr "Não há nenhum tipo de conteúdo disponível." +msgid "Simple" +msgstr "Simples" +msgid "Above" +msgstr "Acima" +msgid "Number of values" +msgstr "Quantidade de valores" +msgid "" +"Warning! Changing this setting after data has been created could " +"result in the loss of data!" +msgstr "" +"Atenção! Mudar esta configuração após os dados terem sido " +"cadastrados poderá resultar em perda de dados!" +msgid "" +"The content module, a required component of the Content Construction " +"Kit (CCK), allows administrators to associate custom fields with " +"content types. In Drupal, content types are used to define the " +"characteristics of a post, including the title and description of the " +"fields displayed on its add and edit pages. Using the content module " +"(and the other helper modules included in CCK), custom fields beyond " +"the default \"Title\" and \"Body\" may be added. CCK features are " +"accessible through tabs on the <a href=\"@content-types\">content " +"types administration page</a>. (See the <a href=\"@node-help\">node " +"module help page</a> for more information about content types.)" +msgstr "" +"O módulo Content, um componente exigido do Content Construction Kit " +"(CCK), permite que um administrador associe campos personalizados a " +"tipos de conteúdos. No Drupal, tipos de conteúdos são usados para " +"definir características de um node, incluíndo o título e a " +"descrição dos campos exibidos nas páginas de criação e de " +"edição do conteúdo. Usando o módulo Content (e os outros módulos " +"úteis incluídos no CCK), campos personalizados, muito além do " +"\"Título\" e \"Corpo\", poderão ser adicionados. Os recursos do CCK " +"estão acessíveis pelas abas na <a href=\"@content-types\">página de " +"administração de tipos de conteúdo</a>. (Consulte a <a " +"href=\"@node-help\">página de ajuda do módulo</a> para mais " +"informações sobre tipos de conteúdo)." +msgid "" +"When adding a custom field to a content type, you determine its type " +"(whether it will contain text, numbers, or references to other " +"objects) and how it will be displayed (either as a text field or area, " +"a select box, checkbox, radio button, or autocompleting field). A " +"field may have multiple values (i.e., a \"person\" may have multiple " +"e-mail addresses) or a single value (i.e., an \"employee\" has a " +"single employee identification number). As you add and edit fields, " +"CCK automatically adjusts the structure of the database as necessary. " +"CCK also provides a number of other features, including intelligent " +"caching for your custom data, an import and export facility for " +"content type definitions, and integration with other contributed " +"modules." +msgstr "" +"Quando você adiciona um campo personalizado a um tipo de conteúdo, " +"você deve determinar o tipo do campo (se ele irá conter texto, " +"números ou referência a outros nodes) e como ele deverá ser exibido " +"(seja como um campo ou uma caixa de texto, uma seleção em lista, uma " +"caixa de seleção, botões rádio, um campo de texto com " +"autocompletar, etc). Um campo pode ter múltiplos valores (por exemplo " +"uma pessoa pode ter vários endereços de e-mail), ou um único valor " +"(por exemplo, um empregado só pode ter um único número de registro " +"em uma empresa). Quando você adiciona e edita campos, o CCK ajusta " +"automaticamente a estrutura do banco de dados necessária para " +"armazená-los. O CCK também oferece vários recursos, como cache " +"inteligente para campos personalizados, um sistema de " +"importação/exportação dos formulários criados, além de um " +"sistema de integração com vários outros módulos." +msgid "" +"Custom field types are provided by a set of optional modules included " +"with CCK (each module provides a different type). The <a " +"href=\"@modules\">modules page</a> allows you to enable or disable CCK " +"components. A default installation of CCK includes:" +msgstr "" +"Tipos personalizados de campo são gerados por uma série de módulos " +"incluídos com o CCK. Cada módulo gera um tipo diferente de campo. A " +"<a href=\"@modules\">página de módulos</a> permite que você " +"habilite ou desabilite componentes do CCK. Uma instalação padrão do " +"CCK inclui:" +msgid "" +"<em>number</em>, which adds numeric field types, in integer, decimal " +"or floating point form. You may define a set of allowed inputs, or " +"specify an allowable range of values. A variety of common formats for " +"displaying numeric data are available." +msgstr "" +"<em>número</em>, que permite adicionar campos numéricos, no formato " +"inteiro, decimal ou ponto flutuante. Você pode definir o conjunto de " +"entradas permitidas, ou especificar um intervalo de valores " +"permitidos. Vários formatos comuns para exibir dados numéricos " +"também estão disponiveis." +msgid "" +"<em>text</em>, which adds text field types. A text field may contain " +"plain text only, or optionally, may use Drupal's input format filters " +"to securely manage rich text input. Text input fields may be either a " +"single line (text field), multiple lines (text area), or for greater " +"input control, a select box, checkbox, or radio buttons. If desired, " +"CCK can validate the input to a set of allowed values." +msgstr "" +"<em>texto</em>, que permite adicionar campos de texto. Um campo de " +"texto pode conter texto puro ou, se você quiser, usar os filtros de " +"formato de entrada do Drupal para gerenciar de maneira segura a " +"entrada dos dados. A entrada de texto pode ser por um campo de texto " +"de uma linha, uma caixa de texto com várias linhas, ou, para maior " +"controle de entrada, uma seleção em lista suspensa, uma caixa de " +"seleção ou botões rádio. Caso você desejar, o CCK pode restringir " +"a entrada a uma série de valores permitidos que você " +"pré-configure." +msgid "" +"<em>nodereference</em>, which creates custom references between Drupal " +"nodes. By adding a <em>nodereference</em> field and two different " +"content types, for instance, you can easily create complex " +"parent/child relationships between data (multiple \"employee\" nodes " +"may contain a <em>nodereference</em> field linking to an \"employer\" " +"node)." +msgstr "" +"<em>referência a nodes</em>, que permite criar campos que referenciam " +"outros nodes no site. Ao adicionar um campo de <em>referência a " +"nodes</em> e dois tipos de conteúdo, você pode criar relações " +"complexas de itens principais e secundários entre os dados (por " +"exemplo, nodes de \"empregados\" podem ter um campo de referência que " +"os liga a um mesmo node \"empregador\")." +msgid "" +"<em>userreference</em>, which creates custom references to your sites' " +"user accounts. By adding a <em>userreference</em> field, you can " +"create complex relationships between your site's users and posts. To " +"track user involvement in a post beyond Drupal's standard <em>Authored " +"by</em> field, for instance, add a <em>userreference</em> field named " +"\"Edited by\" to a content type to store a link to an editor's user " +"account page." +msgstr "" +"<em>userreference</em>, que permite criar campos que referenciam " +"contas de usuários de site. Ao adicionar um campo de <em>referência " +"a usuários</em>, você pode criar relacões complexas entre os " +"usuários do site e os nodes. Por exemplo, se você quiser acompanhar " +"o envolvimento do usuário em um node, além do campo padrão do " +"Drupal <em>criado por</em>, é possível adicionar um campo de " +"referência chamado \"Monitorado por\" a um tipo de conteúdo e " +"armazenar um link para a página da de perfil de um usuário." +msgid "" +"<em>fieldgroup</em>, which creates collapsible fieldsets to hold a " +"group of related fields. A fieldset may either be open or closed by " +"default. The order of your fieldsets, and the order of fields within a " +"fieldset, is managed via a drag-and-drop interface provided by content " +"module." +msgstr "" +"<em>grupo de campos</em>, que permite adicionar conjuntos expansíveis " +"para manter um grupo de campos relacionados. Um grupo também pode " +"estar aberto ou fechado por padrão. A ordem dos seus grupos, e a " +"ordem dos campos dentro deles é gerenciável através de uma " +"interface arrastar-e-soltar oriunda do módulo Content." +msgid "" +"For more information, see the online handbook entry for <a " +"href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK " +"project page</a>." +msgstr "" +"Para mais informações, consulte a ajuda online sobre o <a href=\"@ " +"handbook-cck\">CCK</a> ou a <a href=\"@project-cck\">página do " +"projeto</a>." +msgid "" +"Configure how this content type's fields and field labels should be " +"displayed when it's viewed in teaser and full-page mode." +msgstr "" +"Configurar como os campos e rótulos de campos devem ser exibidos em " +"nodes deste tipo de conteúdo." +msgid "" +"Configure how this content type's fields should be displayed when it's " +"rendered in the following contexts." +msgstr "" +"Configurar como este tipo de conteúdo deve ser exibido nos seguintes " +"contextos." +msgid "!title: !required" +msgstr "!title: !required" +msgid "Add another item" +msgstr "Novo item" +msgid "Full node" +msgstr "Node completo" +msgid "Search Index" +msgstr "Índice de busca" +msgid "Search Result" +msgstr "Resultado da busca" +msgid "Updating field type %type with module %module." +msgstr "Atualizando o tipo de campo %type com o módulo %module." +msgid "Updating widget type %type with module %module." +msgstr "Atualizando o tipo de widget %type com o módulo %module." +msgid "Manage fields" +msgstr "Gerenciar campos" +msgid "Remove field" +msgstr "Remover campo" +msgid "Allows administrators to define new content types." +msgstr "Permite que administradores definam novos tipos de conteúdo." +msgid "" +"Advanced usage only: PHP code that returns a keyed array of allowed " +"values. Should not include <?php ?> delimiters. If this field is " +"filled out, the array returned by this code will override the allowed " +"values list above." +msgstr "" +"Uso avançado apenas: código PHP que deverá retornar um array " +"chaveado com os valores permitidos. Não inclua os delimitadores " +"<?php ?> Se o campo estiver preenchido, o array retornado pelo " +"código vai sobrescrever os valores da lista acima." +msgid "Trimmed" +msgstr "Cortado" +msgid "Used in" +msgstr "Usado em" +msgid "No fields have been defined for any content type yet." +msgstr "Ainda não há nenhum campo definido em nenhum tipo de conteúdo." +msgid "no styling" +msgstr "sem estilo" +msgid "simple" +msgstr "simples" +msgid "fieldset" +msgstr "conjunto de campos" +msgid "fieldset - collapsible" +msgstr "conjunto de campos - colapsável" +msgid "fieldset - collapsed" +msgstr "conjunto de campos - colapsado" +msgid "Added field %label." +msgstr "O campo %label foi adicionado." +msgid "There was a problem adding field %label." +msgstr "Ocorreu um problema ao adicionar o campo %label." +msgid "There was a problem creating field %label." +msgstr "Ocorreu um problema na criação do campo %label." +msgid "Are you sure you want to remove the field %field?" +msgstr "Você tem certeza de que deseja remover o campo %field?" +msgid "" +"If you have any content left in this field, it will be lost. This " +"action cannot be undone." +msgstr "" +"Caso você tenha algum conteúdo armazenado neste campo, ele será " +"perdido. Esta ação não pode ser desfeita." +msgid "Removed field %field from %type." +msgstr "O campo %field foi removido de %type." +msgid "There was a problem deleting %field from %type." +msgstr "Ocorreu um problema ao remover %field de %type." +msgid "" +"These settings apply only to the %field field as it appears in the " +"%type content type." +msgstr "" +"Essas configurações se aplicam ao campo %field apenas no tipo de " +"conteúdo %type." +msgid "" +"These settings apply to the %field field in every content type in " +"which it appears." +msgstr "" +"Essas configurações se aplicam ao campo %field em todos os tipos de " +"conteúdo em que ele apareça." +msgid "Save field settings" +msgstr "Salvar as configurações do campo" +msgid "" +"The default value PHP code returned an incorrect value.<br/>Expected " +"format: <pre>!sample</pre> Returned value: @value" +msgstr "" +"O valor que o código PHP retornou é inválido.<br/>Formato esperado: " +"<pre>!sample</pre>. Valor retornado: @value" +msgid "The default value is invalid." +msgstr "O valor padrão é inválido." +msgid "Saved field %label." +msgstr "O campo %label foi salvo." +msgid "The update has encountered an error." +msgstr "Foi encontrado um erro na atualização." +msgid "The database has been altered and data has been migrated or deleted." +msgstr "O banco de dados foi alterado e dados foram migrados ou apagados." +msgid "An error occurred and database alteration did not complete." +msgstr "Ocorreu um erro e a alteração do banco de dados não foi completada." +msgid "Processing %title" +msgstr "Processando %title" +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "1 item for processado com sucesso:" +msgstr[1] "@count itens foram processados com sucesso:" +msgid "" +"Content fields table %old_name has been renamed to %new_name and field " +"instances have been updated." +msgstr "" +"A tabela de campos de conteúdo %old_name foi renomeada para %new_name " +"e as instâncias do campo foram atualizadas." +msgid "The content fields table %name has been deleted." +msgstr "A tabela de campos de conteúdo %name foi apagada." +msgid "Referenced node ID" +msgstr "Identificador do referenciado" +msgid "Referenced node title" +msgstr "Título do node referenciado" +msgid "Raw number value" +msgstr "Valor numérico não filtrado" +msgid "Formatted number value" +msgstr "Valor numérico formatado" +msgid "Raw, unfiltered text" +msgstr "Texto original, não filtrado" +msgid "Formatted and filtered text" +msgstr "Texto formatado e filtrado" +msgid "Referenced user ID" +msgstr "Identificador do usuário referenciado" +msgid "Referenced user name" +msgstr "Nome do usuário referenciado" +msgid "Formatted HTML link to referenced user" +msgstr "Link para o usuário referenciado, em formato HTML" +msgid "Group multiple values" +msgstr "Agrupar múltiplos valores" +msgid "Select the content type to export." +msgstr "Selecione o tipo de conteúdo que deseja exportar." +msgid "Export data" +msgstr "Exportar dados" +msgid "" +"Copy the export text and paste it into another content type using the " +"import function." +msgstr "" +"Copie o texto exportado e cole-o em outro tipo de conteúdo usando a " +"função importar." +msgid "" +"This form will import field definitions exported from another content " +"type or another database.<br/>Note that fields cannot be duplicated " +"within the same content type, so imported fields will be added only if " +"they do not already exist in the selected type." +msgstr "" +"Esse formulário irá importar as definições importadas de outro " +"tipo de conteúdo ou outro banco de dados.<br />Note que campos não " +"podem ser duplicados em um mesmo tipo de conteúdo, então campos " +"importados serão adicionados apenas se eles não existirem no tipo de " +"conteúdo selecionado." +msgid "<Create>" +msgstr "<Criar>" +msgid "" +"Select the content type to import these fields into.<br/>Select " +"<Create> to create a new content type to contain the fields." +msgstr "" +"Selecione o tipo de conteúdo para o qual você deseja importar esses " +"campos.<br /> Selecione <?Criar> para criar um novo tipo de " +"conteúdo e inserir esses campos." +msgid "Import data" +msgstr "Importar dados" +msgid "Paste the text created by a content export into this field." +msgstr "" +"Cole neste campo o texto criado pela exportação de um tipo de " +"conteúdo." +msgid "The import data is not valid import text." +msgstr "Os dados de importação não são válidos." +msgid "" +"The following modules must be enabled for this import to work: " +"%modules." +msgstr "" +"Os seguintes módulos devem ser habilitados para que a importação " +"funcione: %modules." +msgid "The content type %type already exists in this database." +msgstr "O tipo de conteúdo %type já existe no banco de dados." +msgid "Exiting. No import performed." +msgstr "Saindo. Nada foi importado." +msgid "" +"An error has occurred adding the content type %type.<br/>Please check " +"the errors displayed for more details." +msgstr "" +"Ocorreu um erro ao tentar adicionar o tipo de conteúdo %type.<br " +"/>Por favor verifique os erros exibidos para mais informações." +msgid "" +"The imported field %field_label (%field_name) was not added to %type " +"because that field already exists in %type." +msgstr "" +"O campo importado %field_label (%field_name) não foi adicionado a " +"%type porque esse campo já existe em %type." +msgid "" +"The field %field_label (%field_name) was added to the content type " +"%type." +msgstr "" +"O campo %field_label (%field_name) foi adicionado ao tipo de conteúdo " +"%type." +msgid "" +"An error occurred when exporting the 'display settings' data for the " +"field %field_name.<br/>The db error is: '%db_err'." +msgstr "" +"Ocorreu um erro ao tentar exportar os dados das \"configurações de " +"exibição\" do campo %field_name.<br />O erro no banco de dados foi: " +"\"%db_err\"." +msgid "Content Copy" +msgstr "Copiar conteúdo" +msgid "Enables ability to import/export field definitions." +msgstr "" +"Habilita a função de importar/exportar definições de campos e " +"tipos de conteúdo." +msgid "field_name" +msgstr "field_name" +msgid "view " +msgstr "ver " +msgid "" +"Please <a href=\"!url\">configure your field permissions</a> " +"immediately. All fields are inaccessible by default." +msgstr "" +"Por favor <a href=\"!url\">configure imediatamente as permissões para " +"seus campos</a>! Todos os campos ficam inacessíveis por padrão." +msgid "Content Permissions" +msgstr "Permissões ao conteúdo" +msgid "Set field-level permissions for CCK fields." +msgstr "Configurar permissões por campo para campos CCK" +msgid "These settings apply to the group in the node editing form." +msgstr "" +"Essas configurações se aplicam ao grupo no formulário de edição " +"do node." +msgid "always open" +msgstr "sempre aberto" +msgid "collapsible" +msgstr "dobrável" +msgid "collapsed" +msgstr "dobrado" +msgid "Instructions to present to the user on the editing form." +msgstr "Instruções a serem exibidas ao usuário no formulário de edição." +msgid "These settings apply to the group on node display." +msgstr "Essas configurações se aplicam a um grupo na exibição de node." +msgid "A description of the group." +msgstr "Uma descrição do grupo." +msgid "Are you sure you want to remove the group %label?" +msgstr "Você tem certeza de que deseja remover o grupo %label?" +msgid "The group %group_name has been removed." +msgstr "O grupo %group_name foi removido." +msgid "Fieldgroup" +msgstr "Grupo de campos" +msgid "Node reference" +msgstr "Referência a um node" +msgid "Store the ID of a related node as an integer value." +msgstr "" +"Armazena o identificador de um node relacionado como um número " +"inteiro." +msgid "Content types that can be referenced" +msgstr "Tipos de conteúdos que podem ser referenciados" +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Avançado - nodes que podem ser referenciados (View)" +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "" +"Forneça uma lista de argumentos a serem passados à view, " +"separando-os por vírgulas." +msgid "Title (link)" +msgstr "Título (link)" +msgid "Title (no link)" +msgstr "Título (sem link)" +msgid "Autocomplete text field" +msgstr "Campo de texto com autocompletar" +msgid "Nodereference autocomplete" +msgstr "Autocompletar referência a nodes" +msgid "Node Reference" +msgstr "Referência a nodes" +msgid "Defines a field type for referencing one node from another." +msgstr "Define um tipo de campo para um node referenciar outro." +msgid "Store a number in the database as an integer." +msgstr "Armazenar um número no banco de dados no formato \"inteiro\"." +msgid "Decimal" +msgstr "Decimal" +msgid "Store a number in the database in a fixed decimal format." +msgstr "Armazenar um número no banco de dados no formato \"decimal\"." +msgid "Float" +msgstr "Ponto flutuante" +msgid "Store a number in the database in a floating point format." +msgstr "Armazenar um número no banco de dados no formato \"ponto flutuante\"." +msgid "Minimum" +msgstr "Mínimo" +msgid "Precision" +msgstr "Precisão" +msgid "" +"The total number of digits to store in the database, including those " +"to the right of the decimal." +msgstr "" +"O quantidade total de dígitos armazenados no banco de dados, " +"incluindo aqueles à direita da casa decimal." +msgid "The number of digits to the right of the decimal." +msgstr "O número de dígitos à direita da casa decimal." +msgid "Decimal marker" +msgstr "Marcador decimal" +msgid "The character users will input to mark the decimal point in forms." +msgstr "" +"O caractere que os usuários vão usar nos formulários para marcar o " +"decimal." +msgid "" +"Define a string that should be prefixed to the value, like $ or €. " +"Leave blank for none. Separate singular and plural values with a pipe " +"(pound|pounds)." +msgstr "" +"Defina um texto a ser prefixada ao valor. Por exemplo, $, R$ ou €. " +"Deixe em branco para não usar nada. Se quiser, separe sufixos para " +"singular e plural com um pipe (quilo|quilos)." +msgid "" +"Define a string that should suffixed to the value, like m², m/s², " +"kb/s. Leave blank for none. Separate singular and plural values with a " +"pipe (pound|pounds)." +msgstr "" +"Defina um texto a ser sufixado ao valor. Por exemplo, m², m/s², " +"kb/s. Deixe em branco para não usar nada. Se quiser, separe sufixos " +"para singular e plural com um pipe (quilo|quilos)." +msgid "Allowed values" +msgstr "Valores permitidos" +msgid "\"Minimum\" must be a number." +msgstr "O \"Mínimo\" deve ser um número." +msgid "\"Maximum\" must be a number." +msgstr "O \"Máximo\" deve ser um número." +msgid "unformatted" +msgstr "não formatado" +msgid "Defines numeric field types." +msgstr "Define campos numéricos." +msgid "" +"For a 'single on/off checkbox' widget, define the 'off' value first, " +"then the 'on' value in the <strong>Allowed values</strong> section. " +"Note that the checkbox will be labeled with the label of the 'on' " +"value." +msgstr "" +"Para um dispositivo no formato de checkbox de 'liga/desliga', defina o " +"valor de 'desligado' primeiro e então o valor 'ligado' na seção dos " +"<strong>Valores permitidos</strong>. Note que o checkbox irá ter o " +"label do valor 'ligado'." +msgid "" +"The 'checkboxes/radio buttons' widget will display checkboxes if the " +"multiple values option is selected for this field, otherwise radios " +"will be displayed." +msgstr "" +"O widget 'caixas de seleção/botões de opção' irá mostrar as " +"caixas de seleção se a opção de valores múltiplos estiver " +"selecionada para este campo, caso contrário serão mostrados botões " +"de opção." +msgid "Check boxes/radio buttons" +msgstr "Caixas de seleção/botões de opção" +msgid "Single on/off checkbox" +msgstr "Checkbox simples de liga/desliga" +msgid "Option Widgets" +msgstr "Widgets opcionais" +msgid "" +"Defines selection, check box and radio button widgets for text and " +"numeric fields." +msgstr "" +"Define widgets de seleção em lista, caixa de seleção e botões de " +"rádio para os campos de texto e numéricos." +msgid "Store text in the database." +msgstr "Armazena texto no banco de dados." +msgid "Text area (multiple rows)" +msgstr "Caixa de texto (várias linhas)" +msgid "Defines simple text field types." +msgstr "Define tipos simples de campos de texto." +msgid "User reference" +msgstr "Referência a usuários" +msgid "Store the ID of a related user as an integer value." +msgstr "" +"Armazena o identificador de um usuário referenciado no formato de um " +"número inteiro." +msgid "User roles that can be referenced" +msgstr "Papéis de usuários que podem ser selecionados" +msgid "User status that can be referenced" +msgstr "Status dos usuários que podem ser referenciados" +msgid "Reverse link" +msgstr "Link reverso" +msgid "" +"If selected, a reverse link back to the referencing node will " +"displayed on the referenced user record." +msgstr "" +"Se esta opção for selecionada, um link para o node referenciador " +"será exibido na página do usuário." +msgid "Userreference autocomplete" +msgstr "Autocompletar da referência aos usuários" +msgid "User Reference" +msgstr "Referência a usuários" +msgid "Defines a field type for referencing a user from a node." +msgstr "Define um tipo de campo para um node referenciar um usuário." +msgid "All users" +msgstr "Todos os usuários" +msgid "Active users" +msgstr "Usuários ativos" +msgid "Print" +msgstr "Imprimir" +msgid "Locked" +msgstr "Travado" +msgid "" +"Instructions to present to the user below this field on the editing " +"form.<br />Allowed HTML tags: @tags" +msgstr "" +"Instruções para apresentar ao usuário abaixo deste campo, no " +"formulário de edição.<br/>Tags HTML permitidas: @tags" +msgid "<none>" +msgstr "<nenhum>" +msgid "You're not allowed to input PHP code." +msgstr "Você não tem premissão para inserir código PHP." +msgid "" +"This PHP code was set by an administrator and will override any value " +"specified above." +msgstr "" +"Este código PHP foi definido pelo administrador e irá sobrescrever " +"qualquer valor especificado anteriormente." +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "" +"Usar código PHP nas configurações do campo (perigoso - conceda com " +"cuidado)" +msgid "A file has been pre-loaded for import." +msgstr "Um arquivo foi pré-carregado para ser importado." +msgid "Content fieldgroup" +msgstr "Conteúdo do grupo de campos" +msgid "" +"Text to display if group has no data. Note that title will not display " +"unless overridden." +msgstr "" +"Texto exibido se o grupo não tiver nenhum dado. Note que o título " +"não será exibido a não ser que esteja sobrescrito." +msgid "Node from reference" +msgstr "Node da referência" +msgid "" +"Adds a node from a node reference in a node context; if multiple nodes " +"are referenced, this will get the first referenced node only." +msgstr "" +"Adiciona um node a partir de um node reference em um contexto de node; " +"se múltiplos nodes forem referenciados, isto irá pegar apenas o " +"primeiro node referenciado." +msgid "Node reference field" +msgstr "Campo de referência a nodes" +msgid "" +"The possible values this field can contain. Enter one value per line, " +"in the format key|label. The key is the value that will be stored in " +"the database, and it must match the field storage type (%type). The " +"label is optional, and the key will be used as the label if no label " +"is specified.<br />Allowed HTML tags: @tags" +msgstr "" +"Os valores que este campo pode conter. Insira um valor por linha, no " +"formato chave|rótulo. A chave é o valor que será armazenado no " +"banco de dados, e deve ser compatível com o tipo de armazenamento do " +"campo (%type). O rótulo é opcional e a chave será usada como o " +"rótulo se nenhum rótulo for especificado.<br />Tags HTML permitidas: " +"@tags" +msgid "" +"This PHP code was set by an administrator and will override the " +"allowed values list above." +msgstr "" +"O código PHP foi configurado por um administrador e irá sobrescrever " +"os valores inseridos acima." +msgid "User from reference" +msgstr "Usuário referenciado" +msgid "" +"Adds a user from a user reference in a node context; if multiple users " +"are referenced, this will get the first referenced user only." +msgstr "" +"Adiciona um usuário a partir de uma referência em um contexto de " +"node. Se múltiplos usuários forem referenciados apenas o primeiro " +"será usado." +msgid "User reference field" +msgstr "Campo de referência a usuários" +msgid "Show @count value(s)" +msgstr "Exibir @count valor(es)" +msgid "starting from @count" +msgstr "começando de @count" +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Valores permitidos" +msgid "%name: illegal value." +msgstr "%name: valor ilegal." +msgid "%name: the value may not be longer than %max characters." +msgstr "%name: você não pode digitar mais do que %max caracteres." +msgid "Autocomplete matching" +msgstr "Busca do autocompletar" +msgid "Starts with" +msgstr "Começa com" +msgid "Load a referenced user" +msgstr "Carregar uma referência a um usuário" +msgid "Content containing the user reference field" +msgstr "Conteúdo com o campo de referência a usuário" +msgid "Referenced user" +msgstr "Usuário referenciado" +msgid "Load a referenced node" +msgstr "Carrega um node referenciado" +msgid "Content containing the node reference field" +msgstr "O conteúdo que contém o campo de referencia a nodes" +msgid "Referenced content" +msgstr "Conteúdo referenciado" +msgid "Populate a field" +msgstr "Preencher um campo" +msgid "Select the machine-name of the field." +msgstr "Selecione o nome de máquina do campo" +msgid "Revision information" +msgstr "Informações da revisão" +msgid "" +"Select the method used to collect autocomplete suggestions. Note that " +"<em>Contains</em> can cause performance issues on sites with thousands " +"of users." +msgstr "" +"Selecione o método para coletar sugestões do autocompletar. Note que " +"<em>Contém</em> pode ficar um pouco lento em sites com centenas de " +"nodes." +msgid "View used to select the nodes" +msgstr "View usada para selecionar os nodes" +msgid "%name: this post can't be referenced." +msgstr "%name: este post não pode ser referenciado." +msgid "Node module form." +msgstr "Formulário do módulo Node." +msgid "Locale module form." +msgstr "Formulário do módulo Locale." +msgid "Taxonomy module form." +msgstr "Formulário do módulo Taxonomia." +msgid "Poll title" +msgstr "Título da Enquete" +msgid "%name: this field cannot hold more than @count values." +msgstr "%name: este campo não aceita mais de @count valores." +msgid "'@column' => value for @column" +msgstr "'@column' => valor para @column" +msgid "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" +msgstr "" +"return array(\r\n" +" 0 => array(@columns),\r\n" +" // Talvez você deseje parar aqui.\r\n" +" // Informe mais valores se quiser que o \"valor padrão\" " +"múltiplo:\r\n" +" 1 => array(@columns),\r\n" +" 2 => ...\r\n" +");" +msgid "" +"Create a list of options as a list in <strong>Allowed values " +"list</strong> or as an array in PHP code. These values will be the " +"same for %field in all content types." +msgstr "" +"Criar uma lista de opções como uma lista em <strong>Lista dos " +"valores permitidos</strong> ou como um array no código PHP. Estes " +"valores serão os mesmos para o %field em todos os tipos de conteúdo." +msgid "You need to specify the 'allowed values' for this field." +msgstr "Você deve especificar os \"valores permitidos\" para este campo." +msgid "Change basic information" +msgstr "Alterar as informações básicas" +msgid "Fieldset" +msgstr "Conjunto de campos" +msgid "Translation settings" +msgstr "Configurações da tradução" +msgid "" +"Select the method used to collect autocomplete suggestions. Note that " +"<em>Contains</em> can cause performance issues on sites with thousands " +"of nodes." +msgstr "" +"Selecione o método usado para coletar as sugestões do autocompletar. " +"Note que <em>Contém</em> pode acarretar em problemas de desempenho em " +"um site com milhares de nodes." +msgid "%name: title mismatch. Please check your selection." +msgstr "%name: título errado. Por favor confira sua seleção." +msgid "Path settings" +msgstr "Configurações do endereço" +msgid "%name: the value may be no smaller than %min." +msgstr "%name: o valor não pode ser menor que %min." +msgid "%name: the value may be no larger than %max." +msgstr "%name: o valor não pode ser mais que %max." +msgid "%name: found no valid user with that name." +msgstr "%name: não há um usuário com esse nome." +msgid "Field label" +msgstr "Rótulo do campo" +msgid "Form settings" +msgstr "Configurações do formulário" +msgid "Type of group." +msgstr "Tipo de grupo." +msgid "" +"If unchecked, each item in the field will create a new row, which may " +"appear to cause duplicates. This setting is not compatible with " +"click-sorting in table displays." +msgstr "" +"Se você não selecionar esta opção, cada item no campo será criado " +"como uma nova linha, o que pode ocasionar resultados duplicados. Esta " +"configuração não é compatível com tabelas que tenham a opção de " +"reordenar com um clique." +msgid "" +"Some updates are still pending. Please return to <a " +"href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "" +"Algumas atualizações ainda estão pendentes. Por favor, retorne para " +"<a href=\"@update-php\">update.php</a> e execute as atualizações " +"restantes." +msgid "Some updates are still pending.<br/>Please re-run the update script." +msgstr "" +"Algumas atualizações estão pendentes.<br/>Por favor, rode novamente " +"o script de atualização." +msgid "Comment module form." +msgstr "Formulário do módulo Comentário." +msgid "Translation module form." +msgstr "Formulário do módulo Tradução." +msgid "Menu module form." +msgstr "Formulário do módulo Menu." +msgid "Book module form." +msgstr "Formulário do módulo Livro." +msgid "Path module form." +msgstr "Formulário do módulo Caminho." +msgid "Poll module title." +msgstr "Título do módulo Enquete." +msgid "Poll module choices." +msgstr "Opções do módulo enquete" +msgid "Poll module settings." +msgstr "Configurações do módulo Enquete." +msgid "Upload module form." +msgstr "Formulário do módulo Upload." +msgid "" +"Updates for CCK-related modules are not run until the modules are " +"enabled on the <a href=\"@admin-modules-path\">administer modules " +"page</a>. When you enable them, you'll need to return to <a " +"href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "" +"Atualizações para módulo relacionados ao CCK não são rodadas até " +"que os módulos sejam ativados na <a " +"href=\"@admin-modules-path\">área de administração de módulos</a>. " +"Após habilitá-los, você deve retornar ao script <a " +"href=\"@update-php\">update.php</a> e rodar as atualizações " +"faltantes." +msgid "" +"!module.module has updates but cannot be updated because " +"content.module is not enabled.<br />If and when content.module is " +"enabled, you will need to re-run the update script. You will continue " +"to see this message until the module is enabled and updates are run." +msgstr "" +"O módulo !module tem atualizações disponíveis, mas não foi " +"possível executá-las porque o módulo content.module não está " +"habilitado.<br />Quando (ou se) o módulo Content for ativado, você " +"deverá executar o script de atualização novamente. Você " +"continuará a ver esta mensagem até que o módulo seja ativado e " +"todas as atualizações, rodadas." +msgid "" +"!module.module has updates and is available in the modules folder but " +"is not enabled.<br />If and when it is enabled, you will need to " +"re-run the update script. You will continue to see this message until " +"the module is enabled and updates are run." +msgstr "" +"O módulo !module tem atualizações disponíveis no diretório de " +"módulos, mas ele não está ativo.<br />Quando (ou se) ele for " +"ativado, você deverá executar o script de atualização novamente. " +"Você continuará a ver esta mensagem até que o módulo seja ativado " +"e todas as atualizações, rodadas." +msgid "CCK - No Views integration" +msgstr "CCK - Sem integração com Views" +msgid "" +"CCK integration with Views module requires Views 6.x-2.0-rc2 or " +"greater." +msgstr "" +"Integração do CCK com o módulo Views requer Views 6.x-2.0-rc2 ou " +"superior." +msgid "manage fields" +msgstr "gerenciar campos" +msgid "» Add a new content type" +msgstr "» Adicionar novo tipo de conteúdo" +msgid "@field_name (Locked)" +msgstr "@field_name (Travado)" +msgid "" +"This content type has inactive fields. Inactive fields are not " +"included in lists of available fields until their modules are enabled." +msgstr "" +"Este tipo de conteúdo possui campos inativos. Um campo inativo não " +"será incluído na lista de campos disponíveis enquanto o seu módulo " +"não for ativado." +msgid "" +"!field (!field_name) is an inactive !field_type field that uses a " +"!widget_type widget." +msgstr "" +"!field (!field_name) é um campo inativo !field_type que usa um widget " +"!widget_type." +msgid "- Select a field type -" +msgstr "- Selecione um tipo de campo -" +msgid "- Select a widget -" +msgstr "- Selecione um widget -" +msgid "Field name (a-z, 0-9, _)" +msgstr "Nome do campo (a-z, 0-9, _)" +msgid "Type of data to store." +msgstr "Tipo de dados a armazenar." +msgid "Form element to edit the data." +msgstr "Elemento de formulário para editar os dados." +msgid "- Select an existing field -" +msgstr "- Selecione um campo existente -" +msgid "Field to share" +msgstr "Campo para compartilhar" +msgid "Group name (a-z, 0-9, _)" +msgstr "Nome do grupo (a-z, 0-9, _)" +msgid "Add new field: you need to provide a label." +msgstr "Adicionar um novo campo: você precisa escolher um rótulo." +msgid "Add new field: you need to provide a field name." +msgstr "Adicionar novo campo: você precisa escolher nome para o campo." +msgid "" +"Add new field: the field name %field_name is invalid. The name must " +"include only lowercase unaccentuated letters, numbers, and " +"underscores." +msgstr "" +"Adicionar novo campo: o nome do campo %field_name é inválido. O nome " +"tem não pode ter nada além de letras minúsculas não acentuadas, " +"números e underscores (_)." +msgid "" +"Add new field: the field name %field_name is too long. The name is " +"limited to 32 characters, including the 'field_' prefix." +msgstr "" +"Adicionar novo campo: o nome do campo %field_name é longo demais. O " +"nome não pode ter mais de 32 caracteres, incluindo o prefixo " +"\"field_\"." +msgid "Add new field: the name 'field_instance' is a reserved name." +msgstr "" +"Adicionar novo campo: \"field_instance\" é um nome reservado pelo " +"sistema." +msgid "Add new field: the field name %field_name already exists." +msgstr "Adicionar novo campo: já existe um campo chamado %field_name." +msgid "Add new field: you need to select a field type." +msgstr "Adicionar novo campo: você precisa selecionar um tipo para o campo." +msgid "Add new field: you need to select a widget." +msgstr "Adicionar novo campo: você precisa selecionar um widget." +msgid "Add new field: invalid widget." +msgstr "Adicionar novo campo: widget inválido." +msgid "Add existing field: you need to provide a label." +msgstr "Adicionar campo existente: você precisa escolher um rótulo." +msgid "Add existing field: you need to select a field." +msgstr "Adicionar campo existente: você precisa selecionar um campo." +msgid "Add existing field: you need to select a widget." +msgstr "Adicionar campo existente: você precisa selecionar um widget." +msgid "Add existing field: invalid widget." +msgstr "Adicionar campo existente: widget inválido." +msgid "" +"The field %label cannot be added to a content type because it is " +"locked." +msgstr "" +"O campo %label não pôde ser adicionado ao tipo de conteúdo porque " +"ele está travado." +msgid "" +"There are no fields configured for this content type. You can add new " +"fields on the <a href=\"@link\">Manage fields</a> page." +msgstr "" +"Não há nenhum campo configurado para este tipo de conteúdo. Você " +"pode adicionar novos campos no página de <a href=\"@link\">gerenciar " +"campos</a>." +msgid "@type: @field (@label)" +msgstr "@type: @field (@label)" +msgid "Edit basic information" +msgstr "Editar informações básicas" +msgid "The machine-readable name of the field. This name cannot be changed." +msgstr "" +"O nome-identificador para o campo. Esse identificador não pode ser " +"alterado." +msgid "" +"A human-readable name to be used as the label for this field in the " +"%type content type." +msgstr "" +"O nome do campo, usado como rótulo do campo no tipo de conteúdo " +"%type." +msgid "" +"The type of data you would like to store in the database with this " +"field. This option cannot be changed." +msgstr "" +"O tipo de dado que você gostaria de armazenar no banco de dados com " +"esse campo. Essa opção não pode ser alterada." +msgid "" +"The type of form element you would like to present to the user when " +"creating this field in the %type content type." +msgstr "" +"O tipo de elemento do formulário que você gostaria de apresentar ao " +"usuário quando criar este campo no tipo de conteúdo %type." +msgid "Updated basic settings for field %label." +msgstr "As configurações básicas para o campo %label foram atualizadas." +msgid "There was a problem updating the basic settings for field %label." +msgstr "" +"Houve um problema ao tentar atualizar as configurações básicas do " +"campo %label." +msgid "This field is <strong>locked</strong> and cannot be removed." +msgstr "Este campo está <strong>travado</strong> e não pode ser removido." +msgid "The field %field is locked and cannot be edited." +msgstr "O campo %field está travado e não pode ser editado." +msgid "%type basic information" +msgstr "Informações básicas de %type" +msgid "" +"Advanced usage only: PHP code that returns a default value. Should not " +"include <?php ?> delimiters. If this field is filled out, the " +"value returned by this code will override any value specified above. " +"Expected format: <pre>!sample</pre>To figure out the expected format, " +"you can use the <em>devel load</em> tab provided by <a " +"href=\"@link_devel\">devel module</a> on a %type content page." +msgstr "" +"Apenas para uso avançado: Código PHP que retorne um valor padrão. " +"Não deve incluir os delimitadores <?php ?>. Caso este campo " +"esteja preenchido, o valor retornado por este código irá " +"sobrescrever qualquer valor especificado acima. Formato esperado: " +"<pre>!sample</pre>. Para ter uma idéia do resultado esperado, você " +"pode utilizar a aba <em>devel load</em>, fornecida pelo <a " +"href=\"@link_devel\">módulo devel</a> em uma página de conteúdo do " +"%type." +msgid "Maximum number of values users can enter for this field." +msgstr "" +"Quantidade máxima de valores que os usuários podem digitar neste " +"campo." +msgid "" +"'Unlimited' will provide an 'Add more' button so the users can add as " +"many values as they like." +msgstr "" +"Se você escolher \"ilimitado\", o formulário terá um botão " +"\"Adicionar mais\" para que o usuário possa inserir quantos valores " +"ele quiser." +msgid "The PHP code for 'default value' returned @value, which is invalid." +msgstr "" +"O código PHP para o 'valor padrão' retornou o valor @value, que é " +"inválido." +msgid "%name must be an integer." +msgstr "%name deve ser um número inteiro." +msgid "%name must be a positive integer." +msgstr "%name tem que ser um número inteiro e positivo." +msgid "%name must be a number." +msgstr "%name deve ser um número." +msgid "" +"You should make sure that the used field exists in the given content " +"type." +msgstr "" +"Você deve se certificar que o campo em uso existe no tipo de " +"conteúdo fornecido." +msgid "Advanced: Specify the fields value with PHP code" +msgstr "Avançado: Especificar o valor dos campos com código PHP." +msgid "" +"Advanced usage only: PHP code that returns the value to set. Should " +"not include <?php ?> delimiters. If this field is filled out, " +"the value returned by this code will override any value specified " +"above. Expected format: <pre>!sample</pre>Using <a " +"href=\"@link_devel\">devel.module's</a> 'devel load' tab on a content " +"page might help you figure out the expected format." +msgstr "" +"Somente para uso avançado: um código PHP que retorna o valor para o " +"conjunto. Não use os delimitadores & lt;?php ?> Se o campo " +"retornado por esse código vai sobrescrever qualquer valor inserido " +"acima. Formato esperado: <pre>!sample</pre> A aba \"dev load\", do <a " +"href=\"@link_devel\">módulo Devel</a>, pode ajudar você a saber o " +"formato esperado." +msgid "You have to return the default value in the expected format." +msgstr "Você tem que retornar o valor padrão no formato especificado." +msgid "Populate @node's field '@field'" +msgstr "Preencher o campo \"@field\" de @node" +msgid "Field has value" +msgstr "O campo tem um valor" +msgid "" +"You should make sure that the used field exists in the given content " +"type. The condition returns TRUE, if the selected field has the given " +"value." +msgstr "" +"Você deve se certificar que o campo existe no tipo de conteúdo " +"especificado. O condicional retorna TRUE se o campo selecionado " +"possuir o valor fornecido." +msgid "Field has changed" +msgstr "O campo foi alterado" +msgid "Content containing changes" +msgstr "Conteúdo com mudanças" +msgid "Content not containing changes" +msgstr "Conteúdo sem mudanças" +msgid "@node's field '@field' has value" +msgstr "O campo \"@field\" de @node tem um valor" +msgid "Select the machine-name of the field to look at." +msgstr "Selecione o identificador do campo a ser analisado." +msgid "@node's field '@field' has been changed" +msgstr "O campo \"@field\" de @node foi alterado" +msgid "Referenced node unfiltered title. WARNING - raw user input." +msgstr "" +"Título não filtrado do node referenciado. ATENÇÃO - usará a " +"entrada não filtrada de um usuário." +msgid "Formatted html link to the referenced node." +msgstr "Link para o node referenciado, em formato HTML" +msgid "Relative path alias to the referenced node." +msgstr "URL relativa para o node referenciado." +msgid "Absolute path alias to the referenced node." +msgstr "URL absoluta para o node referenciado." +msgid "Relative path alias to the referenced user." +msgstr "URL relativa para o usuário referenciado." +msgid "Absolute path alias to the referenced user." +msgstr "URL absoluta para o usuário referenciado." +msgid "Field: @widget_label (@field_name) - @field_type" +msgstr "Campo: @widget_label (@field_name) - @field_type" +msgid "Field on the referenced node." +msgstr "Campo no conteúdo referenciado." +msgid "" +"Configure how the label is going to be displayed. This option takes no " +"effect when \"Override title\" option is enabled, the specified block " +"title is displayed instead." +msgstr "" +"Configure como o rótulo do campo será exibido. Esta opção não tem " +"efeito se a opção \"Sobrescrever título\" estiver marcada." +msgid "Field formatter" +msgstr "Formatador do campo" +msgid "Select a formatter." +msgstr "Selecione um formatador." +msgid "\"@s\" field: @widget_label (@field_name) - @field_type" +msgstr "Campo \"@s\": @widget_label (@field_name) - @field_type" +msgid "@label (!name)" +msgstr "@label (!name)" +msgid "@label (!name) - !column" +msgstr "@label (!name) - !column" +msgid "@label-truncated - !column" +msgstr "@label-truncated - !column" +msgid "Appears in: @types" +msgstr "Aparece em: @types" +msgid "<No value>" +msgstr "<nenhum valor>" +msgid "Widget label (@label)" +msgstr "Rótulo do widget (@label)" +msgid "Custom label" +msgstr "Rótulo personalizado" +msgid "(first item is 0)" +msgstr "(o primeiro item é 0)" +msgid "(start from last values)" +msgstr "(começar dos últimos valores)" +msgid "" +"The delta allows you to select which item in a multiple value field to " +"key the relationship off of. Select \"1\" to use the first item, \"2\" " +"for the second item, and so on. If you select \"All\", each item in " +"the field will create a new row, which may appear to cause duplicates." +msgstr "" +"O delta permite que você selecione qual item, em um campo de " +"múltiplos valores, será a chave do relacionamento. Selecione \"1\" " +"para usar o primeiro item, \"2\" para o segundo, e assim por diante. " +"Caso você selecione \"Todos\", cada um dos itens criará uma nova " +"linha, e poderão surgir resultados duplicados." +msgid "" +"The delta allows you to select which item in a multiple value field " +"will be used for sorting. Select \"1\" to use the first item, \"2\" " +"for the second item, and so on. If you select \"All\", each item in " +"the field will create a new row, which may appear to cause duplicates." +msgstr "" +"O delta permite que você selecione que item, em um campo com mais de " +"um valor, será usado para ordenação. Selecione \"1\" para ordenar " +"pelo primeiro valor, \"2\" para ordenar pelo segundo, etc. Se você " +"selecionar \"Todos\", cada item no campo vai gerar uma nova linha, " +"criando, aparentemente, duplicatas." +msgid "You need to provide a label." +msgstr "Você precisa escolher um rótulo." +msgid "You need to provide a group name." +msgstr "Você deve escolher um nome para o grupo." +msgid "" +"The group name %group_name is invalid. The name must include only " +"lowercase unaccentuated letters, numbers, and underscores." +msgstr "" +"O nome do grupo %group_name é inválido. O nome não deve ter além " +"de letras minúsculas sem acento, espaços, números e underscores " +"(_)." +msgid "" +"The group name %group_name is too long. The name is limited to 32 " +"characters, including the 'group_' prefix." +msgstr "" +"O nome do grupo %group_name é longo demais O nome não deve ter mais " +"que 32 caracteres, incluindo o prefixo 'group_'." +msgid "The group name %group_name already exists." +msgstr "Já existe um grupo com o nome %group_name." +msgid "Add new group:" +msgstr "Adicionar um novo grupo:" +msgid "Add new group: you need to provide a label." +msgstr "Adicionar um novo gupo: você precisa escolher um rótulo." +msgid "Add new group: you need to provide a group name." +msgstr "Adicionar um novo grupo: você deve escolher um nome para o grupo." +msgid "Standard group" +msgstr "Grupo normal" +msgid "Create display groups for CCK fields." +msgstr "Criar grupos para exibir os campos CCK." +msgid "Field group: @group in @type" +msgstr "Grupo de campos: @group em @type" +msgid "All fields from this field group on the referenced node." +msgstr "Todos os campos desse grupo de campos no node referenciado." +msgid "Field group label" +msgstr "Rótulo do grupo de campos" +msgid "" +"Configure how the field group label is going to be displayed. This " +"option takes no effect when \"Override title\" option is enabled, the " +"specified block title is displayed instead." +msgstr "" +"Configura a visualização do rótulo do grupo de campos. Essa opção " +"não tem efeito quando a opção \"Sobrescrever Título\" está " +"ativada. O título especificado no bloco será usado no lugar." +msgid "Fieldset - Collapsible" +msgstr "Conjunto de campos - Fechável" +msgid "Fieldset - Collapsed" +msgstr "Conjunto de campos - Fechado" +msgid "Field group format" +msgstr "Formato do grupo de campos" +msgid "This option allows you to configure the field group format." +msgstr "Esta opção permite configurar o formato do grupo de campos." +msgid "\"@s\" field group: @group in @type" +msgstr "Conjunto de campos \"@s\": @group em @type" +msgid "" +"Note that if the field has multiple values, only the first content " +"node will be loaded." +msgstr "" +"Note que, se o campo tiver múltiplos valores, apenas o conteúdo do " +"primeiro node será carregado." +msgid "There are no nodereference fields defined." +msgstr "Não há nenhum campo de referência a nodes." +msgid "" +"<p>Choose the \"Views module\" view that selects the nodes that can be " +"referenced.<br />Note:</p>" +msgstr "" +"<p>Escolha a view (do módulo Views) que seleciona os nodes que podem " +"ser referenciados.<br />Nota:</p>" +msgid "" +"<ul><li>Only views that have fields will work for this " +"purpose.</li><li>This will discard the \"Content types\" settings " +"above. Use the view's \"filters\" section instead.</li><li>Use the " +"view's \"fields\" section to display additional informations about " +"candidate nodes on node creation/edition form.</li><li>Use the view's " +"\"sort criteria\" section to determine the order in which candidate " +"nodes will be displayed.</li></ul>" +msgstr "" +"<ul><li>Apenas views que tenham campos vão funcionar aqui.</li><li>Ao " +"selecionar esta opção, as configurações do \"Tipos de conteúdo\" " +"acima serão descartadas. Use um filtro na view para substituir essa " +"função.</li><li>Use a seção de campos da view para exibir " +"informações adicionais sobre os nodes no formulário de " +"criação/edição do node.</li><li>Use o \"Critério de ordenamento\" " +"da view para determinar em que ordem os nodes candidatos serão " +"exibidos.</li></ul>" +msgid "" +"<p>The list of nodes that can be referenced can be based on a \"Views " +"module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" +"<p>A lista de nodes que podem ser referenciados pode ser gerada por " +"uma view. No entanto, nenhuma view adequada foi encontrada.<br " +"/>Nota:</p>" +msgid "%name: invalid input." +msgstr "%name: entrada inválida." +msgid "%name: found no valid post with that title." +msgstr "%name: não foi encontrado nenhum node válido com esse título." +msgid "Only numbers and decimals are allowed in %field." +msgstr "Apenas números decimais são permitidos em %field." +msgid "Only numbers are allowed in %field." +msgstr "Você só pode digitar números em %field." +msgid "" +"Only numbers and the decimal character (%decimal) are allowed in " +"%field." +msgstr "" +"Você pode digitar apenas números e o caractere decimal (%decimal) no " +"campo %field." +msgid "" +"Note that if the field has multiple values, only the first user will " +"be loaded." +msgstr "" +"Note que, se este campo tiver múltiplos valores, apenas o primeiro " +"será carregado." +msgid "There are no userreference fields defined." +msgstr "Não há nenhum campo definido para referenciar usuários." +msgid "Advanced - Users that can be referenced (View)" +msgstr "Avançado - Usuários que podem ser referenciados (View)" +msgid "View used to select the users" +msgstr "View usada para selecionar os usuários" +msgid "" +"<p>Choose the \"Views module\" view that selects the users that can be " +"referenced.<br />Note:</p>" +msgstr "" +"<p>Escolha a view (do módulo \"Views\") para selecionar os usuários " +"que podem ser referenciados.<br />Nota:</p>" +msgid "" +"<ul><li>Only views that have fields will work for this " +"purpose.</li><li>This will discard the \"Referenceable Roles\" and " +"\"Referenceable Status\" settings above. Use the view's \"filters\" " +"section instead.</li><li>Use the view's \"fields\" section to display " +"additional informations about candidate users on user creation/edition " +"form.</li><li>Use the view's \"sort criteria\" section to determine " +"the order in which candidate users will be displayed.</li></ul>" +msgstr "" +"<ul><li>Apenas views que contenham campos irão funcionar para este " +"propósito.</li><li>Com isso serão descartados as configurações " +"acima para os \"Papéis referenciáveis\" e \"Status " +"referenciáveis\". Então, utilize a seção dos \"filtros\" do " +"módulo Views.</li><li>Utilize os \"campos\" do módulo Views para " +"exibir informações adicionais sobre os usuários candidatos no " +"ofrmulário de criação/edição.</li><li>Utilize o \"critério de " +"ordenação\" do módulo Views para determinar a ordem na qual os " +"usuários candidatos serão exibidos.</li></ul>" +msgid "" +"<p>The list of user that can be referenced can be based on a \"Views " +"module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" +"<p>A lista de usuários que podem ser referenciados pode ser gerada " +"por uma view do módulo \"Views\". No entanto, nenhuma view apropriada " +"foi encontrada.<br />Nota:</p>" +msgid "%name: invalid user." +msgstr "%name: usuário inválido." +msgid "New field" +msgstr "Novo campo" +msgid "Existing field" +msgstr "Campo existente" +msgid "New group" +msgstr "Novo grupo" +msgid "" +"Add fields and groups to the content type, and arrange them on content " +"display and input forms." +msgstr "" +"Adicionar campos e grupos para o tipo de conteúdo e organizar a na " +"exibição do conteúdo e no formulário de cadastro." +msgid "" +"You can add a field to a group by dragging it below and to the right " +"of the group." +msgstr "" +"Se você quiser adicionar um campo a um grupo, basta clicar e " +"arrastá-lo diretamente para o grupo desejado." +msgid "" +"Note: Installing the <a href=\"!adv_help\">Advanced help</a> module " +"will let you access more and better help." +msgstr "" +"Nota: se você instalar o módulo <a href=\"!adv_help\">Advanced " +"help</a>, você terá acesso a mais textos de ajuda, mais detalhados." +msgid "" +"Use the 'Exclude' checkbox to exclude an item from the !content value " +"passed to the node template." +msgstr "" +"Use a caixa de seleção \"Excluir\" se quiser remover um item do " +"valor !content passado ao template do node." +msgid "@label (!name) - delta" +msgstr "@label (!name) - delta" +msgid "@label-truncated - delta" +msgstr "@label-truncated - delta" +msgid "Delta - Appears in: @types" +msgstr "Delta - Aparece em: @types" +msgid "" +"This form will process a content type and one or more fields from that " +"type and export the settings. The export created by this process can " +"be copied and pasted as an import into the current or any other " +"database. The import will add the fields to an existing content type " +"or create a new content type that includes the selected fields." +msgstr "" +"Este formulário irá processar um tipo de conteúdo e um ou mais " +"campos deste tipo e exportar as configurações. A exportação criada " +"neste processo pode ser copiada e colada como uma importação no " +"banco de dados atual ou em qualquer outro. A importação irá " +"adicionar os campos a um tipo de conteúdo existente ou irá criar um " +"novo tipo de conteúdo que inclua os campos selecionados." +msgid "Blocked users" +msgstr "Usuários bloqueados" +msgid "The 'referenceable_status' option for %field has been fixed." +msgstr "A opção \"referenceable_status\" para %field foi corrigida." diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/pt.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/pt.po new file mode 100644 index 0000000000000000000000000000000000000000..d740eed6a81ebcfaf28707c80bde3ce9746be5d7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/pt.po @@ -0,0 +1,822 @@ +# $Id$ +# Portuguese translation of Drupal (general) +# Copyright 2007 Fernando Silva <fernando.silva@openquest.pt> +# Generated from files: +# text.module,v 1.41.2.11 2007/02/25 23:57:55 yched +# number.module,v 1.34.2.20 2007/03/01 04:51:54 yched +# content_admin.inc,v 1.28.2.29 2007/02/24 03:06:45 yched +# fieldgroup.module,v 1.1.4.26 2007/02/27 02:45:37 yched +# content_copy.module,v 1.1.2.6 2007/03/01 00:28:01 yched +# content.module,v 1.90.2.38 2007/03/05 22:09:33 yched +# nodereference.module,v 1.39.2.17 2007/03/05 21:58:47 yched +# userreference.module,v 1.30.2.16 2007/03/05 21:58:47 yched +# content.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# content_copy.info,v 1.1.2.4 2007/01/08 13:29:21 karens +# fieldgroup.info,v 1.1.2.2 2007/01/05 11:57:46 yched +# nodereference.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# number.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# optionwidgets.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# text.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# userreference.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# content_crud.inc,v 1.4.2.11 2007/01/26 12:34:56 karens +# content_views.inc,v 1.2.2.11 2007/02/26 13:52:04 yched +# optionwidgets.module,v 1.10.2.7 2007/02/09 19:36:39 yched +# optionwidgets.install,v 1.1.4.5 2007/01/25 17:23:26 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: content.module\n" +"POT-Creation-Date: 2007-03-05 23:30+0100\n" +"PO-Revision-Date: 2007-07-13 19:05+0100\n" +"Last-Translator: Fernando Silva <fernando.silva@openquest.pt>\n" +"Language-Team: Fernando Silva <fernando.silva@openquest.pt>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: content_admin.inc:203;207;368;749 fieldgroup.module:84;510 +msgid "Label" +msgstr "Denominação" + +#: content_admin.inc:203 fieldgroup.module:510 +msgid "Group" +msgstr "Grupo" + +#: content_admin.inc:362 content_copy.module:158;231 +msgid "Submit" +msgstr "Submeter" + +#: content_admin.inc:410;415 fieldgroup.module:477;485 +msgid "<Hidden>" +msgstr "<Escondido>" + +#: content_admin.inc:413 fieldgroup.module:476 +msgid "Above" +msgstr "Acima" + +#: content_admin.inc:481 content.module:100 +msgid "Add field" +msgstr "Adicionar campo" + +#: content_admin.inc:686 fieldgroup.module:216 +msgid "Remove" +msgstr "Remover" + +#: content_admin.inc:686 fieldgroup.module:216 +msgid "Cancel" +msgstr "Cancelar" + +#: content_admin.inc:763 fieldgroup.module:106 +msgid "Help text" +msgstr "Texto de ajuda" + +#: content_admin.inc:797 number.module:65 text.module:49 +msgid "Php code" +msgstr "Código PHP" + +#: content_admin.inc:803 number.module:71 text.module:55 +msgid "Code" +msgstr "Código" + +#: content.module:59 content_copy.module:129 +msgid "Fields" +msgstr "Campos" + +#: nodereference.module:202 userreference.module:142 +msgid "<none>" +msgstr "<nenhum>" + +#: number.module:57 text.module:41 +msgid "Allowed values list" +msgstr "Lista de valores permitidos" + +#: number.module:61 text.module:45 +msgid "" +"The possible values this field can contain. Enter one value per line, in the " +"format key|label. The key is the value that will be stored in the database and " +"it must match the field storage type, %type. The label is optional and the key " +"will be used as the label if no label is specified." +msgstr "" +"Os valores possíveis que este campo pode conter. Insira um valor por linha, " +"no formato chave|denominação. A chave é o valor que irá ser guardado na base " +"de dados e tem de coincidir com o tipo de dados, %type. A denominação é " +"opcional e a chave será usada como denominação se nenhuma for específicada." + +#: number.module:74 text.module:58 +msgid "" +"Advanced Usage Only: PHP code that returns a keyed array of allowed values. " +"Should not include <?php ?> delimiters. If this field is filled out, the " +"array returned by this code will override the allowed values list above." +msgstr "" + +#: content.info:0 content_copy.info:0 fieldgroup.info:0 nodereference.info:0 number.info:0 optionwidgets.info:0 text.info:0 userreference.info:0 +msgid "CCK" +msgstr "CCK" + +#: content_crud.inc:59 +msgid "The content fields table %name has been created." +msgstr "A tabela de conteúdos de campos %name foi criada." + +#: content_crud.inc:89 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "A tabela %old_name foi renomeada para %new_name e os campos foram actualizados." + +#: content_crud.inc:111 +msgid "The content fields table %name has been deleted." +msgstr "A tabela de conteúdos de campos %name foi eliminada." + +#: content_views.inc:70 +msgid "Group multiple values" +msgstr "Agrupar múltiplos valores" + +#: content_views.inc:71 +msgid "Do not group multiple values" +msgstr "Não agrupar múltipos valores" + +#: content.module:18 +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "Configurar como deverão ser mostrados os campos deste tipo de conteúdo e as denominações de cada campo, quando é visualizado num resumo e página inteira." + +#: content.module:75 +msgid "Edit" +msgstr "Editar" + +#: content.module:82 +msgid "Manage fields" +msgstr "Gerir campos" + +#: content.module:91 +msgid "Display fields" +msgstr "Mostrar campos" + +#: content.module:119 +msgid "Remove field" +msgstr "Remover campo" + +#: content.module:0 +msgid "content" +msgstr "conteúdo" + +#: content.info:0 +msgid "Content" +msgstr "Conteúdo" + +#: content.info:0 +msgid "Allows administrators to define new content types." +msgstr "Permite aos administradores definir novos tipos de conteúdo." + +#: optionwidgets.module:38 +msgid "" +"Create a list of options as a list in <strong>Allowed values</strong> or as an " +"array in Php code at the bottom of this page. These values will be the same " +"for the %field in all content types. " +msgstr "" +"Criar uma lista de opções como uma lista de <strong>Valores permitidos</strong> ou " +"como um <em>array</em> em código PHP no fim desta página. Estes valores serão os mesmos " +"para o %field em todos os tipos de conteúdo." + +#: optionwidgets.module:40 +msgid " For a single on/off checkbox, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section." +msgstr "Para uma única caixa de selecção, defina o valor 'off' primeiro, e em seguida o valor 'on' na secção <strong>Valores permitidos</strong>." + +#: optionwidgets.module:43 +msgid " The Check boxes/radio buttons widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "O mecanismo de selecção mostrará caixas de selecção se a opção de múltiplos valores estiver seleccionada para este campo, de outra forma <em>radios</em> serão mostrados." + +#: optionwidgets.module:200 +msgid "N/A" +msgstr "N/A" + +#: optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Mecanismos de Opção" + +#: optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "Define selecção, caixa de selecção e radio para campos numéricos e de texto." + +#: text.module:25 +msgid "Plain text" +msgstr "Texto simples" + +#: text.module:25 +msgid "Filtered text (user selects input format)" +msgstr "Texto filtrado (o utilizador selecciona o formato de introdução de conteúdos)" + +#: text.module:28 +msgid "Text processing" +msgstr "Processamento de texto" + +#: text.module:127 +msgid "%label is longer than %max characters." +msgstr "%label é maior que %max caracteres." + +#: text.info:0 +msgid "Text" +msgstr "Texto" + +#: text.info:0 +msgid "Defines simple text field types." +msgstr "Define campos simples de texto." + +#: userreference.module:27 +msgid "User roles that can be referenced" +msgstr "Grupos de utilizador que podem ser referenciados" + +#: userreference.module:65 +msgid "%name : Invalid user." +msgstr "Utilizador inválido: %name." + +#: userreference.info:0 +msgid "User Reference" +msgstr "Referência a utilizador" + +#: userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "Define um campo para referenciar um utilizador a partir de um nó." + +#: optionwidgets.install:77 +msgid "" +"<div>The allowed values list for %field was updated from </div>" +"<pre>%start</pre><div> to </div><pre>%end</pre><div>You can go to the " +"field settings page to give each option a more user-friendly label." +msgstr "" +"<div>A lista de valores permitidos para %field foi actualizada de </div>" +"<pre>%start</pre><div> a </div><pre>%end</pre><div>Pode ir à página de " +"configurações do campo para dar uma denominação mais amiga do utilizador a cada opção." + +#: optionwidgets.install:80 +msgid "<div>The allowed values list for %field was not changed from </div><pre>%start</pre>" +msgstr "<div>A lista de valores permitidos para %field não foi alterada de </div><pre>%start</pre>" + +#: content_admin.inc:15 +msgid "Field name" +msgstr "Nome do campo" + +#: content_admin.inc:15;518 +msgid "Field type" +msgstr "Tipo do campo" + +#: content_admin.inc:15 +msgid "Used in" +msgstr "Usado em" + +#: content_admin.inc:68 +msgid "There are no groups configured for this content type." +msgstr "Não existe grupos configurados para este tipo de conteúdo." + +#: content_admin.inc:78;352 +msgid "There are no fields configured for this content type." +msgstr "Não existem campos configurados para este tipo de conteúdo." + +#: content_admin.inc:103 +msgid "group" +msgstr "grupo" + +#: content_admin.inc:106;119;144 +msgid "configure" +msgstr "configurar" + +#: content_admin.inc:107;120;145 +msgid "remove" +msgstr "remover" + +#: content_admin.inc:158 +msgid "body" +msgstr "corpo" + +#: content_admin.inc:179 +msgid "Update" +msgstr "Actualizar" + +#: content_admin.inc:203;207;510 +msgid "Name" +msgstr "Nome" + +#: content_admin.inc:203;207;368 +msgid "Type" +msgstr "Tipo" + +#: content_admin.inc:203;207 +msgid "Weight" +msgstr "Peso" + +#: content_admin.inc:203;207 +msgid "Operations" +msgstr "Operações" + +#: content_admin.inc:271 +msgid "No fields have been added to this group." +msgstr "Nenhum campo foi adicionado a este grupo." + +#: content_admin.inc:276 +msgid "!label (!name)" +msgstr "" + +#: content_admin.inc:311 +msgid "Updated field groups." +msgstr "Grupos de campos actualizados." + +#: content_admin.inc:322 +msgid "Updated group weights." +msgstr "Pesos do grupo actualizados." + +#: content_admin.inc:333 +msgid "Updated field weights." +msgstr "Pesos do campo actualizados." + +#: content_admin.inc:368 +msgid "Field" +msgstr "Campo" + +#: content_admin.inc:399 +msgid "Your settings have been saved." +msgstr "As suas configurações foram gravadas." + +#: content_admin.inc:414 +msgid "Inline" +msgstr "Em linha" + +#: content_admin.inc:440 +msgid "Teaser" +msgstr "Resumo" + +#: content_admin.inc:441 +msgid "Full" +msgstr "Completo" + +#: content_admin.inc:472 +msgid "Add existing field" +msgstr "Adicionar campo existente" + +#: content_admin.inc:507 +msgid "Create new field" +msgstr "Criar novo campo" + +#: content_admin.inc:513 +msgid "" +"The machine-readable name of the field.<br/>Allowed characters : " +"unaccentuated a-z, numbers and _. All other characters will be discarded.<br/>" +"You'll be able to choose a human-readable label for the field on next page" +msgstr "" +"O nome de sistema do campo.<br />Caracteres permitidos: caracteres não acentuados a-z, " +"números e _. Todos os outros caracteres serão eliminados.<br />" +"Poderá escolher uma denominação amigável para este campo na próxima página" + +#: content_admin.inc:526 +msgid "Create field" +msgstr "Criar campo" + +#: content_admin.inc:538 +msgid "No field modules are enabled. You need to <a href=\"!modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "Nenhum módulo de campos está activo. Tem de <a href=\"!modules_url\">activar um</a>, como <em>text.module</em>, antes de poder adicionar novos campos." + +#: content_admin.inc:594 +msgid "Added field %label." +msgstr "Adicionado campo %label." + +#: content_admin.inc:606 +msgid "The field name %field_name already exists." +msgstr "O nome do campo %field_name já existe." + +#: content_admin.inc:610 +msgid "The field name %field_name is invalid." +msgstr "O nome do campo %field_name é inválido." + +#: content_admin.inc:661 +msgid "Created field %label." +msgstr "Criado o campo %label." + +#: content_admin.inc:683 +msgid "Are you sure you want to remove the field %field?" +msgstr "Tem a certeza que pretende eliminar o campo %field?" + +#: content_admin.inc:685 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Se este campo tem algum conteúdo, ele será perdido. Esta acção é irreverssível." + +#: content_admin.inc:704 +msgid "Removed field %field from %type." +msgstr "Remover o campo %field do %type." + +#: content_admin.inc:727 +msgid "Widget settings" +msgstr "Configurações do mecanismo" + +#: content_admin.inc:728 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Estas configurações aplicam-se apenas ao campo %field quando aparece no tipo de conteúdo %type." + +#: content_admin.inc:742 +msgid "Widget" +msgstr "Mecanismo" + +#: content_admin.inc:766 +msgid "Instructions to present to the user below this field on the editing form." +msgstr "Instruções para apresentar ao utilizador abaixo deste campo no formulário de edição." + +#: content_admin.inc:775 +msgid "Default value" +msgstr "Valor por omissão" + +#: content_admin.inc:807 +msgid "" +"Advanced Usage Only: PHP code that returns a default value. Should not " +"include <?php ?> delimiters.<br/>If this field is filled out, the value " +"returned by this code will override any value in the textfield above." +msgstr "" +"Apenas para utilização avançada: código PHP que devolve um valor por omissão. " +"Não deve conter os delimitadores <?php ?>.<br /> Se este campo for preenchido, " +"o valor devolvido por este código vai re-escrever o valor acima especificado." + +#: content_admin.inc:813 +msgid "Data settings" +msgstr "Configurações de dados" + +#: content_admin.inc:814 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Estas configurações aplicam-se ao campo %field em qualquer tipo de conteúdo onde apareça." + +#: content_admin.inc:818 +msgid "Required" +msgstr "Obrigatório" + +#: content_admin.inc:823 +msgid "Multiple values" +msgstr "Valores múltiplos" + +#: content_admin.inc:834 +msgid "Save field settings" +msgstr "Gravar as configurações do campo" + +#: content_admin.inc:888 +msgid "The default value php code must return an array like array(0 => array('value' => 'myvalue')) but returned @value." +msgstr "o código PHP do valor por omissão tem de devolver um <em>array</em> como <em>array(0 => array('valor' => 'meuvalor'))</em>, no entanto devolveu @value." + +#: content_admin.inc:926 +msgid "The default value php code created @value which is invalid." +msgstr "O valor por omissão @value do código PHP é inválido." + +#: content_admin.inc:929 +msgid "The default value is invalid." +msgstr "O valor por omissão é inválido." + +#: content_admin.inc:986 +msgid "Saved field %field." +msgstr "Campo %field guardado." + +#: content_admin.inc:1284;1381 +msgid "No PostgreSQL mapping found for %type data type." +msgstr "Nenhum mapeamento PostgreSQL encontrado para o tipo de dados %type." + +#: content_admin.inc:1284;1381 +msgid "database" +msgstr "base de dados" + +#: content_copy.module:35 +msgid "Export" +msgstr "Exportar" + +#: content_copy.module:44 +msgid "Import" +msgstr "Importar" + +#: content_copy.module:81 +msgid "" +"This form will process a content type and one or more fields from that type " +"and export the settings. The export created by this process can be copied and " +"pasted as an import into the current or any other database. The import will add " +"the fields to into an existing content type or create a new content type that " +"includes the selected fields." +msgstr "" +"Este formulário processará o tipo de conteúdo e um ou mais campos desse tipo, " +"exportando as suas configurações. A exportação criada por este processo pode ser " +"copiada e colada como uma importação na base de dados actual ou noutra. A importação " +"adicionará os campos dentro de um tipo de conteúdo existente ou cria um novo tipo " +"de conteúdo para incluir os campos seleccionados." + +#: content_copy.module:90 +msgid "Types" +msgstr "Tipos" + +#: content_copy.module:94 +msgid "Select the content type to export." +msgstr "Seleccione o tipo de conteúdo para exportar." + +#: content_copy.module:119 +msgid "Groups" +msgstr "Grupos" + +#: content_copy.module:123 +msgid "Select the group definitions to export from %type." +msgstr "Seleccione as definições de grupo para exportar do %type." + +#: content_copy.module:133 +msgid "Select the field definitions to export from %type." +msgstr "Seleccione as definições de campo para exportar de %type." + +#: content_copy.module:143 +msgid "Export data" +msgstr "Exportar dados" + +#: content_copy.module:148 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Copie o texto de exportação e cole-o noutro tipo de conteúdo utilizando a função de importação." + +#: content_copy.module:214 +msgid "" +"This form will import field definitions exported from another content type or " +"another database.<br/>Note that fields cannot be duplicated within the same " +"content type, so imported fields will be added only if they do not already " +"exist in the selected type." +msgstr "" +"Este formulário importa definições de campo exportadas de outro tipo de conteúdo ou " +"de outra base de dados.<br />Note que os campos não podem ser duplicados dentro do mesmo " +"tipo de conteúdo, assim os campos importados apenas serão adicionados se eles ainda " +"não existirem no tipo seleccionado." + +#: content_copy.module:217 +msgid "<Create>" +msgstr "<Criar>" + +#: content_copy.module:219 +msgid "Content type" +msgstr "Tipo de conteúdo" + +#: content_copy.module:220 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Seleccione o tipo de conteúdo para onde pretende importar estes campos.<br />Seleccione <Criar> para criar um novo tipo de conteúdo para conter os campos." + +#: content_copy.module:225 +msgid "Import data" +msgstr "Importar dados" + +#: content_copy.module:227 +msgid "Paste the text created by a content export into this field." +msgstr "Cole o texto, criado por uma exportação de conteúdo, neste campo." + +#: content_copy.module:255 +msgid "The import data is not valid import text." +msgstr "Os dados de importação não são um texto válido de importação." + +#: content_copy.module:300 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "Os módulos seguintes tem de estar activos para que esta importação funcione: %modules." + +#: content_copy.module:306;320 +msgid "<create>" +msgstr "<criar>" + +#: content_copy.module:308 +msgid "The content type %type already exists in this database." +msgstr "O tipo de conteúdo %type já existe nesta base de dados." + +#: content_copy.module:315 +msgid "Exiting. No import performed." +msgstr "Nenhuma importação realizada." + +#: content_copy.module:332 +msgid "An error has occured adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Ocorreu um erro ao adicionar o tipo de conteúdo%type.<br/>Por favor verifique os erros mostrados para mais detalhes." + +#: content_copy.module:367 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "O campo importado %field_label (%field_name) não foi adicionado ao %type porque esse campo já existe no %type." + +#: content_copy.module:388;407 +msgid "An error has occured adding the field %field_label (%field_name).<br/>Please check the errors displayed for more details." +msgstr "Ocorreu um erro ao adicionar o campo %field_label (%field_name).<br/>Por favor verifique os erros mostrados para mais detalhes." + +#: content_copy.module:421 +msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field settings.<br/>Please check the errors displayed for more details." +msgstr "O campo %field_label (%field_name) foi adicionado ao tipo de conteúdo %type, no entanto ocorreu um erro ao actualizar as configurações do campo.<br />Por favor verifique os erros mostrados para mais detalhes." + +#: content_copy.info:0 +msgid "Content Copy" +msgstr "Cópia de Conteúdo" + +#: content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "Activa a funcionalidade de importar/exportar definições de campo." + +#: fieldgroup.module:18 +msgid "Add group" +msgstr "Adicionar grupo" + +#: fieldgroup.module:28;36 +msgid "Edit group" +msgstr "Editar grupo" + +#: fieldgroup.module:66 +msgid "Add" +msgstr "Adicionar" + +#: fieldgroup.module:73 +msgid "Save" +msgstr "Guardar" + +#: fieldgroup.module:92 +msgid "These settings apply to the group in the node editing form" +msgstr "Esta configurações aplicam-se ao grupo no formulário de edição do nó" + +#: fieldgroup.module:96 +msgid "style" +msgstr "estilo" + +#: fieldgroup.module:99 +msgid "always open" +msgstr "sempre aberto" + +#: fieldgroup.module:100 +msgid "collapsible" +msgstr "dobrável" + +#: fieldgroup.module:101 +msgid "collapsed" +msgstr "dobrado" + +#: fieldgroup.module:109 +msgid "Instructions to present to the user on the editing form." +msgstr "Instruções a apresentar ao utilizador no formulário de edição." + +#: fieldgroup.module:115 +msgid "These settings apply to the group on node display." +msgstr "Estas configurações aplicam-se ao grupo na visualização do nó." + +#: fieldgroup.module:119 +msgid "Description" +msgstr "Descrição" + +#: fieldgroup.module:122 +msgid "A description of the group." +msgstr "Uma descrição do grupo." + +#: fieldgroup.module:144 +msgid "The group name %name already exists." +msgstr "O nome do grupo %name já existe." + +#: fieldgroup.module:148 +msgid "The group name %name is invalid." +msgstr "O nome do grupo %name é inválido." + +#: fieldgroup.module:213 +msgid "Are you sure you want to remove the group %label?" +msgstr "Tem a certeza que pretende remover o grupo %label?" + +#: fieldgroup.module:215 +msgid "This action cannot be undone." +msgstr "Esta acção não pode ser desfeita." + +#: fieldgroup.module:277 +msgid "No group" +msgstr "Nenhum grupo" + +#: fieldgroup.module:319 +msgid "Display in group" +msgstr "Mostrar no grupo" + +#: fieldgroup.module:322 +msgid "Select a group, in which the field will be displayed on the editing form." +msgstr "Seleccione um grupo, no qual o campo será mostrado no formulário de edição." + +#: fieldgroup.module:480 +msgid "no styling" +msgstr "nenhum estilo" + +#: fieldgroup.module:481 +msgid "simple" +msgstr "simples" + +#: fieldgroup.module:482 +msgid "fieldset" +msgstr "conjunto de campos" + +#: fieldgroup.module:483 +msgid "fieldset - collapsible" +msgstr "conjunto de campos - dobrável" + +#: fieldgroup.module:484 +msgid "fieldset - collapsed" +msgstr "conjunto de campos - dobrado" + +#: fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "Grupo de campos" + +#: fieldgroup.info:0 +msgid "Create field groups for CCK fields." +msgstr "Criar grupos de campos para campos CCK." + +#: nodereference.module:17 +msgid "node reference autocomplete" +msgstr "completar automaticamente referência a nós" + +#: nodereference.module:42 +msgid "Content types that can be referenced" +msgstr "Tipos de conteúdo que podem ser referenciados" + +#: nodereference.module:51 +msgid "Existing Views" +msgstr "Vistas existentes" + +#: nodereference.module:56 +msgid "Default Views" +msgstr "Vistas por omissão" + +#: nodereference.module:61 +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Avançado - Nós que podem ser referenciados (Vista)" + +#: nodereference.module:67 +msgid "View" +msgstr "Vista" + +#: nodereference.module:70 +msgid "" +"Choose the \"Views module\" view that selects the nodes that can be referenced.<br>Note :" +"<ul><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li>" +"<li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li>" +"<li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "" +"Escolha a vista do \"módulo Vistas\" que selecciona os nós que podem ser referenciados.<br />Nota :<ul>" +"<ul><li>Esta opção vai descartar as configurações \"Tipos de conteúdo\" acima. Em vez disso, utilize a secção \"filtros\" da vista.</li>" +"<li>Utilize a secção \"campos\" da vista para mostrar informação adicional sobre nós candidatos no formulário de criação/edição.</li>" +"<li>Utilize a secção \"critérios de ordenação\" da vista para determinar a ordem na qual os nós candidatos serão mostrados.</li></ul>" + +#: nodereference.module:74 +msgid "View arguments" +msgstr "Argumentos da vista" + +#: nodereference.module:77 +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Disponibiliza uma lista de argumentos separados por vírgula para passar à vista." + +#: nodereference.module:122 +msgid "%name : This post can't be referenced." +msgstr "%name : Esta entrada não pode ser referenciada." + +#: nodereference.module:304 +msgid "%name : Title mismatch. Please check your selection." +msgstr "%name : Título não concidente. Por favor verifique a sua selecção." + +#: nodereference.module:483 +msgid "<empty>" +msgstr "<vazio>" + +#: nodereference.info:0 +msgid "Node Reference" +msgstr "Referência a Nós" + +#: nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "Define um tipo de campo para referir um nó a partir de outro." + +#: number.module:33 +msgid "Minimum" +msgstr "Mínimo" + +#: number.module:38 +msgid "Maximum" +msgstr "Máximo" + +#: number.module:43 +msgid "Prefix" +msgstr "Prefixo" + +#: number.module:46 +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Defina uma frase que deve ser prefixada ao valor, como $ ou €. Deixe vazio para nenhum. Separe os valores singular e plural com uma barra vertical (peso|pesos)." + +#: number.module:50 +msgid "Suffix" +msgstr "Sufixo" + +#: number.module:53 +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds). " +msgstr "Defina uma frase que deve ser sufixada ao valor, como m², m/s², kb/s. Deixe vazio para nenhum. Separe os valores singular e plural com uma barra vertical (peso|pesos)." + +#: number.module:80 +msgid "\"Minimum\" must be a number." +msgstr "\"Mínimo\" tem de ser um número." + +#: number.module:83 +msgid "\"Maximum\" must be a number." +msgstr "\"Máximo\" tem de ser um número." + +#: number.module:138 +msgid "The value of %name may be no smaller than %min." +msgstr "O valor de %name não pode ser menor que %min." + +#: number.module:141 +msgid "The value of %name may be no larger than %max." +msgstr "O valor de %name não pode ser maior que %max." + +#: number.info:0 +msgid "Number" +msgstr "Número" + +#: number.info:0 +msgid "Defines numeric field types." +msgstr "Define campos do tipo numérico." diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/ru.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/ru.po new file mode 100644 index 0000000000000000000000000000000000000000..a4d5b28e5e59a7f6812e04d04be5cd35b518470d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/ru.po @@ -0,0 +1,748 @@ +# $Id$ +# +# Russian translation of Drupal (content_admin.inc) +# Copyright 2007 vadbars <vadbars@mail.ru> +# Generated from file: content_admin.inc,v 1.28.2.14 2007/01/07 03:00:33 yched +# +# Russian translation of Drupal (content_copy.module) +# Copyright 2007 vadbars <vadbars@mail.ru> +# Generated from file: content_copy.module,v 1.1.2.5 2007/01/07 14:43:32 yched +# +# Russian translation of Drupal (fieldgroup.module) +# Copyright 2007 vadbars <vadbars@mail.ru> +# Generated from file: fieldgroup.module,v 1.1.4.12 2007/01/09 15:25:03 karens +# +# Russian translation of Drupal (general) +# Copyright 2007 vadbars <vadbars@mail.ru> +# Generated from files: +# field.php,v 1.7.2.3 2007/01/06 16:22:53 yched +# text.module,v 1.41.2.7 2007/01/07 16:21:11 yched +# number.module,v 1.34.2.6 2007/01/07 14:43:32 yched +# content_admin.inc,v 1.28.2.14 2007/01/07 03:00:33 yched +# fieldgroup.module,v 1.1.4.12 2007/01/09 15:25:03 karens +# content.module,v 1.90.2.25 2007/01/09 14:54:10 karens +# content_copy.module,v 1.1.2.5 2007/01/07 14:43:32 yched +# nodereference.module,v 1.39.2.3 2007/01/07 14:43:32 yched +# userreference.module,v 1.30.2.6 2007/01/07 14:43:32 yched +# content.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# content_copy.info,v 1.1.2.4 2007/01/08 13:29:21 karens +# fieldgroup.info,v 1.1.2.2 2007/01/05 11:57:46 yched +# nodereference.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# number.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# optionwidgets.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# text.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# userreference.info,v 1.2.2.2 2007/01/05 11:57:46 yched +# extractor.php,v 1.24 2007/01/10 21:45:47 goba +# content_crud.inc,v 1.4.2.7 2007/01/07 00:06:36 yched +# content_views.inc,v 1.2.2.5 2007/01/05 11:57:46 yched +# optionwidgets.module,v 1.10.2.3 2007/01/07 14:43:32 yched +# optionwidgets.install,v 1.1.4.3 2007/01/05 11:57:46 yched +# +# Russian translation of Drupal (nodereference.module) +# Copyright 2007 vadbars <vadbars@mail.ru> +# Generated from file: nodereference.module,v 1.39.2.3 2007/01/07 14:43:32 yched +# +msgid "" +msgstr "" +"Project-Id-Version: cck\n" +"POT-Creation-Date: 2007-01-27 19:44+0500\n" +"PO-Revision-Date: 2007-01-28 12:56+0600\n" +"Last-Translator: Maynichev <maynich@gmail.com>\n" +"Language-Team: Russian Drupal Translation Team (RDTT) <translators@drupal.ru>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Poedit-Language: Russian\n" +"X-Poedit-Country: RUSSIAN FEDERATION\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: content_admin.inc:15 +msgid "Field name" +msgstr "Название поля" + +#: content_admin.inc:15;413 +msgid "Field type" +msgstr "Тип поля" + +#: content_admin.inc:15 +msgid "Used in" +msgstr "Используется в" + +#: content_admin.inc:68 +msgid "There are no groups configured for this content type." +msgstr "Нет групп, настроенных для этого типа содержимого." + +#: content_admin.inc:78 +msgid "There are no fields configured for this content type." +msgstr "Нет полей, настроенных для этого типа содержимого." + +#: content_admin.inc:101 +msgid "group" +msgstr "группа" + +#: content_admin.inc:104;117;142 +msgid "configure" +msgstr "настроить" + +#: content_admin.inc:105;118;143 +msgid "remove" +msgstr "удалить" + +#: content_admin.inc:156 +msgid "body" +msgstr "текст" + +#: content_admin.inc:177 +msgid "Update" +msgstr "Обновить" + +#: content_admin.inc:202;206 +msgid "Name" +msgstr "Название" + +#: content_admin.inc:202;206 +msgid "Type" +msgstr "Тип" + +#: content_admin.inc:202 +msgid "Group" +msgstr "Группа" + +#: content_admin.inc:202;206 +msgid "Operations" +msgstr "Действия" + +#: content_admin.inc:270 +msgid "No fields have been added to this group." +msgstr "Нет полей, добавленных в эту группу." + +#: content_admin.inc:275 +msgid "!label (!name)" +msgstr "!label (!name)" + +#: content_admin.inc:311 +msgid "Updated field groups." +msgstr "Обновлены группы полей." + +#: content_admin.inc:322 +msgid "Updated group weights." +msgstr "Обновлены веса групп." + +#: content_admin.inc:333 +msgid "Updated field weights." +msgstr "Обновлены веса полей." + +#: content_admin.inc:367 +msgid "Add existing field" +msgstr "Добавить существующее поле" + +#: content_admin.inc:402 +msgid "Create new field" +msgstr "Создать новое поле" + +#: content_admin.inc:408 +msgid "The human-readable name of this field." +msgstr "Понятное человеку имя этого поля." + +#: content_admin.inc:421 +msgid "Create field" +msgstr "Создать поле" + +#: content_admin.inc:433 +msgid "No field modules are enabled. You need to <a href=\"%modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "Не включены модули полей. Вам надо <a href=\"%modules_url\">включить их</a>, например, text.module, чтобы иметь возможность добавлять новые поля." + +#: content_admin.inc:488 +msgid "Added field %label." +msgstr "Добавлено поле %label." + +#: content_admin.inc:500 +msgid "The field name %field_name already exists." +msgstr "Имя поля %field_name уже существует." + +#: content_admin.inc:504 +msgid "The field name %field_name is invalid." +msgstr "Название поля %field_name неправильное." + +#: content_admin.inc:555 +msgid "Created field %label." +msgstr "Создано поле %label." + +#: content_admin.inc:577 +msgid "Are you sure you want to remove the field %field?" +msgstr "Вы действительно хотите удалить поле %field?" + +#: content_admin.inc:579 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Имеющееся содержание этого поля будет утрачено. Это действие нельзя отменить." + +#: content_admin.inc:598 +msgid "Removed field %field from %type." +msgstr "Поле %field удалено из %type." + +#: content_admin.inc:621 +msgid "Widget settings" +msgstr "Установки элементов выбора" + +#: content_admin.inc:622 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Эти настройки относятся только к полю %field, каким оно появляется в типе содержимого %type." + +#: content_admin.inc:636 +msgid "Widget" +msgstr "Элемент" + +#: content_admin.inc:660 +msgid "Instructions to present to the user below this field on the editing form." +msgstr "Инструкции для пользователя, которые будут показаны в форме редактирования." + +#: content_admin.inc:666 +msgid "Data settings" +msgstr "Настройки данных" + +#: content_admin.inc:667 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Эти настройки относятся к полю %field в каждом типе содержимого, в котором оно появляется." + +#: content_admin.inc:671 +msgid "Required" +msgstr "Обязательно" + +#: content_admin.inc:676 +msgid "Multiple values" +msgstr "Множественный выбор" + +#: content_admin.inc:687 +msgid "Save field settings" +msgstr "Сохранить настройки поля" + +#: content_admin.inc:765 +msgid "Saved field %field." +msgstr "Поле %field записано." + +#: content_admin.inc:1060;1153 +msgid "No PostgreSQL mapping found for %type data type." +msgstr "PostgreSQL mapping не найден для типа %type." + +#: content_admin.inc:1060;1153 +msgid "database" +msgstr "база данных" + +#: content_copy.module:35 +msgid "Export" +msgstr "Экспорт" + +#: content_copy.module:44 +msgid "Import" +msgstr "Импорт" + +#: content_copy.module:81 +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "Эта форма обрабатывает тип содержимого и одно или более поле этого типа и экспортирует настройки. Созданные данные экспорта можно скопировать и вставить в текущую или любую другую базу данных. Импорт добавляет поля в существующий тип содержимого или создает новый тип содержимого, который включает выбранные поля." + +#: content_copy.module:90 +msgid "Types" +msgstr "Типы" + +#: content_copy.module:94 +msgid "Select the content type to export." +msgstr "Выберите тип содержимого для экспорта." + +#: content_copy.module:119 +msgid "Groups" +msgstr "Группы" + +#: content_copy.module:123 +msgid "Select the group definitions to export from %type." +msgstr "Выберите определения групп для экспорта из %type." + +#: content_copy.module:133 +msgid "Select the field definitions to export from %type." +msgstr "Выберите определения полей для экспорта из %type." + +#: content_copy.module:143 +msgid "Export data" +msgstr "Экспортировать данные" + +#: content_copy.module:148 +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Копировать экспортируемый текст и вставить его в другой тип содержимого используя функцию импорта." + +#: content_copy.module:158;231 +msgid "Submit" +msgstr "Отправить" + +#: content_copy.module:214 +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "Эта форма позволяет импортировать определения полей из другого типа содержимого или другой базы данных. <br />Обратите внимание, что не должно быть одинаковых полей в одном и том же типе содержимого, поскольку инпортируемые поля добавляются только, если такие не существуют в выбранном типе содержимого." + +#: content_copy.module:217 +msgid "<Create>" +msgstr "<Создать>" + +#: content_copy.module:219 +msgid "Content type" +msgstr "Тип содержимого" + +#: content_copy.module:220 +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Выберите типы содержимого для импорта в эти поля.<br/>Выберите <Создать> для создания нового типа содержимого, в котором будут использоваться эти поля." + +#: content_copy.module:225 +msgid "Import data" +msgstr "Импорт данных" + +#: content_copy.module:227 +msgid "Paste the text created by a content export into this field." +msgstr "Вставить в это поле текст, созданный с помощью экспорта." + +#: content_copy.module:254 +msgid "The import data is not valid import text." +msgstr "Импортируемые данные содержат неправильный текст для импорта." + +#: content_copy.module:299 +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "Следующие модули должны быть включены, чтобы работал импорт: %modules." + +#: content_copy.module:305;319 +msgid "<create>" +msgstr "<создать>" + +#: content_copy.module:307 +msgid "The content type %type already exists in this database." +msgstr "Тип содержимого %type уже есть в базе данных." + +#: content_copy.module:314 +msgid "Exiting. No import performed." +msgstr "Выход. Импорт не произведен." + +#: content_copy.module:331 +msgid "An error has occured adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Была обнаружена ошибка при добавлении типа содержимого %type.<br/>Подробности в сообщениях об ошибках." + +#: content_copy.module:366 +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "Импортируемое поле %field_label (%field_name) не было добавлено в %type, поскольку оно уже существует в %type." + +#: content_copy.module:387;406 +msgid "An error has occured adding the field %field_label (%field_name).<br/>Please check the errors displayed for more details." +msgstr "Была обнаружена ошибка при добавлении поля %field_label (%field_name).<br/>Подробности в сообщениях об ошибках." + +#: content_copy.module:420 +msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field settings.<br/>Please check the errors displayed for more details." +msgstr "Импортируемое поле %field_label (%field_name) было добавлено в %type, но при обновлении поля была обнаружена ошибка.<br/>Подробности в сообщениях об ошибках." + +#: fieldgroup.module:19 +msgid "Create and order your groups first. Then assign fields to a group by editing the fields." +msgstr "Сначала создайте и упорядочите свои группы. Затем распределите поля по группам, путем редактирования полей." + +#: fieldgroup.module:33 +msgid "Add group" +msgstr "Добавить группу" + +#: fieldgroup.module:43;51 +msgid "Edit group" +msgstr "Изменить группу" + +#: fieldgroup.module:79 +msgid "Add" +msgstr "Добавить" + +#: fieldgroup.module:86 +msgid "Save" +msgstr "Сохранить" + +#: fieldgroup.module:103 +msgid "Collapsible" +msgstr "Сворачиваемая" + +#: fieldgroup.module:108 +msgid "Collapsed" +msgstr "Показывать свернутой" + +#: fieldgroup.module:117 +msgid "Instructions to present to the user on the editing form." +msgstr "Инструкции для пользователя, показываемые в форме редактирования." + +#: fieldgroup.module:124 +msgid "In the node editing form, the heavier groups will sink and the lighter groups will be positioned nearer the top." +msgstr "Более легкие группы в форме изменения материала будут всплывать наверх, а тяжелые - опускаться вниз." + +#: fieldgroup.module:144 +msgid "The group name %name already exists." +msgstr "Имя группы %name уже существует." + +#: fieldgroup.module:148 +msgid "The group name %name is invalid." +msgstr "Имя группы %name неверное." + +#: fieldgroup.module:202 +msgid "Are you sure you want to remove the group %label?" +msgstr "Вы уверены, что хотите отменить удаление группы %label?" + +#: fieldgroup.module:204 +msgid "This action cannot be undone." +msgstr "Это действие нельзя отменить." + +#: fieldgroup.module:266 +msgid "No group." +msgstr "Групп нет." + +#: fieldgroup.module:308 +msgid "Display in group" +msgstr "Показывать в группе" + +#: fieldgroup.module:311 +msgid "Select a group, in which the field will be displayed on the editing form." +msgstr "Выберите группу, в которой поле будет показываться в форме редактирования." + +#: fieldgroup.module:0 +msgid "fieldgroup" +msgstr "группа полей" + +#: field.php:80 +#: text.module:34 +msgid "Maximum length" +msgstr "Максимальная длина" + +#: field.php:83 +#: text.module:37 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "Максимальная длина поля (количество знаков). Оставьте поле пустым для неограниченной длины." + +#: field.php:189;199 +#: number.module:131 +#: text.module:124 +msgid "Illegal value for %name." +msgstr "Неправильное значение для %name." + +#: field.php:326 +#: text.module:209 +msgid "Rows" +msgstr "Колонки" + +#: field.php:334 +#: text.module:217 +msgid "\"Rows\" must be a positive integer." +msgstr "\"Колонок\"должно быть положительным числом." + +#: content_admin.inc:202;206;405;643 +#: fieldgroup.module:97 +msgid "Label" +msgstr "Заголовок" + +#: content_admin.inc:202;206 +#: fieldgroup.module:122 +msgid "Weight" +msgstr "Вес" + +#: content_admin.inc:376 +#: content.module:81 +msgid "Add field" +msgstr "Добавить поле" + +#: content_admin.inc:580 +#: fieldgroup.module:205 +msgid "Remove" +msgstr "Удалить" + +#: content_admin.inc:580 +#: fieldgroup.module:205 +msgid "Cancel" +msgstr "Отменить" + +#: content_admin.inc:657 +#: fieldgroup.module:114 +msgid "Help text" +msgstr "Справочный текст" + +#: content.module:49 +#: content_copy.module:129 +msgid "Fields" +msgstr "Поля" + +#: nodereference.module:181 +#: userreference.module:256 +msgid "<none>" +msgstr "нет" + +#: number.module:38 +#: text.module:41 +msgid "Allowed values list" +msgstr "Список допустимых значений." + +#: number.module:42 +#: text.module:45 +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database and it must match the field storage type, %type. The label is optional and the key will be used as the label if no label is specified." +msgstr "Значения, которые может принимать полеn. Введите по одному полю на строку в виде key|label. key это значение, которое записывается в базу данных и должно быть типа %type. label - необязательное поле, если его не будет, используется значение key." + +#: number.module:46 +#: text.module:49 +msgid "Php code" +msgstr "Код PHP" + +#: number.module:52 +#: text.module:55 +msgid "Code" +msgstr "Код" + +#: number.module:55 +#: text.module:58 +msgid "Advanced Usage Only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Только для экспертов: код PHP, который возвращает массив (keyed array) разрешенных значений. Можно не включать ограничители <?php ?>. Если поле заполнено, то массив, возвращаемый этим кодом, перекроет список разрешенных значений, указанный выше." + +#: content.info:0 +msgid "Content" +msgstr "Содержание" + +#: content.info:0 +msgid "Allows administrators to define new content types." +msgstr "Позволяет администраторам определять новые типы данных." + +#: content.info:0 +#: content_copy.info:0 +#: fieldgroup.info:0 +#: nodereference.info:0 +#: number.info:0 +#: optionwidgets.info:0 +#: text.info:0 +#: userreference.info:0 +msgid "CCK" +msgstr "CCK" + +#: content.info:0 +#: content_copy.info:0 +#: fieldgroup.info:0 +#: nodereference.info:0 +#: number.info:0 +#: optionwidgets.info:0 +#: text.info:0 +#: userreference.info:0 +msgid "cck" +msgstr "cck" + +#: content_copy.info:0 +msgid "Content Copy" +msgstr "Копия содержимого" + +#: content_copy.info:0 +msgid "Enables ability to import/export field definitions." +msgstr "Включает возможность импорта/экспорта определений полей." + +#: fieldgroup.info:0 +msgid "Fieldgroup" +msgstr "Группа полей" + +#: fieldgroup.info:0 +msgid "Create field groups for CCK fields." +msgstr "Создать группу из полей CCK." + +#: nodereference.info:0 +msgid "Node Reference" +msgstr "Связь материала" + +#: nodereference.info:0 +msgid "Defines a field type for referencing one node from another." +msgstr "Определяет тип поля для связи одного материала с другим." + +#: number.info:0 +msgid "Number" +msgstr "Число" + +#: number.info:0 +msgid "Defines numeric field types." +msgstr "Определяет типы числового поля." + +#: optionwidgets.info:0 +msgid "Option Widgets" +msgstr "Выбор опций" + +#: optionwidgets.info:0 +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "Определяет выбор, выбор опций или радиокнопки для текстовых и числовых полей." + +#: text.info:0 +msgid "Text" +msgstr "Текст" + +#: text.info:0 +msgid "Defines simple text field types." +msgstr "Определяет типы полец для простого текста." + +#: userreference.info:0 +msgid "User Reference" +msgstr "Ссылка на пользователя" + +#: userreference.info:0 +msgid "Defines a field type for referencing a user from a node." +msgstr "Определяет тип поля для ссылок на пользователя из материала." + +#: my_extractor.php:664 +msgid "Help called" +msgstr "Справочный текст" + +#: my_extractor.php:665 +msgid "This is some help" +msgstr "Здесь какая-нибудь справка" + +#: my_extractor.php:664 +msgid "help" +msgstr "справка" + +#: my_extractor.php:660 +msgid "access extrator data" +msgstr "иметь доступ к данным экстрактора" + +#: my_extractor.php:660 +msgid "administer extractor data" +msgstr "управлять данными экстрактора" + +#: my_extractor.php:669 +msgid "extractor-cooltype" +msgstr "extractor-cooltype" + +#: my_extractor.php:669 +msgid "extractor-evencooler" +msgstr "extractor-evencooler" + +#: my_extractor.php:0 +msgid "extractor" +msgstr "экстрактор" + +#: content_crud.inc:60 +msgid "The content fields table %name has been created." +msgstr "Таблица полей содержания %name создана." + +#: content_crud.inc:90 +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "Поля таблицы %old_name переименованы в %new_name и значения полей обновлены." + +#: content_crud.inc:112 +msgid "The content fields table %name has been deleted." +msgstr "Поля таблицы %name удалены." + +#: content_views.inc:57 +msgid "Group multiple values" +msgstr "Группировать множественные значения" + +#: content_views.inc:58 +msgid "Do not group multiple values" +msgstr "Не группировать множественные значения" + +#: content.module:65 +msgid "Edit" +msgstr "Изменить" + +#: content.module:72 +msgid "Manage fields" +msgstr "Управлять полями" + +#: content.module:100 +msgid "Remove field" +msgstr "Удалить поле" + +#: number.module:28 +msgid "Minimum" +msgstr "Минимум" + +#: number.module:33 +msgid "Maximum" +msgstr "Максимум" + +#: number.module:61 +msgid "\"Minimum\" must be a number." +msgstr "\"Минимум\" должен быть числом." + +#: number.module:64 +msgid "\"Maximum\" must be a number." +msgstr "\"Максимум\" должен быть числом." + +#: number.module:125 +msgid "The value of %name may be no smaller than %min." +msgstr "Значение %name должно быть не меньше, чем %min." + +#: number.module:128 +msgid "The value of %name may be no larger than %max." +msgstr "Значение %name должно быть не больше, чем %min." + +#: optionwidgets.module:34 +msgid "Create a list of options as a list in Allowed values or as an array in Php code at the bottom of this page. These values will be the same for the %field in all content types. The Check boxes/radio buttons widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "Создает список опций, например, как список (типа \"Разрешенные значения\") или как массив в коде PHP внизу данной страницы. Эти значения долджны быть тем же, что %field во всех типах содержимого. Выбор опций/Радиокнопки покажет выбор опций, если для этого поля выбрана опция множественные значения, иначе будут показаны радиокнопки." + +#: optionwidgets.module:171 +msgid "N/A" +msgstr "нет" + +#: text.module:25 +msgid "Plain text" +msgstr "Простой текст" + +#: text.module:25 +msgid "Filtered text (user selects input format)" +msgstr "Фильтрованный текст (пользователь выбирает формат входа)" + +#: text.module:28 +msgid "Text processing" +msgstr "Обработка текста" + +#: text.module:329 +msgid "%label is longer than %max characters." +msgstr "%label не длиннее %max знаков." + +#: userreference.module:27 +msgid "User roles that can be referenced" +msgstr "Роли пользователей, которые могут ссылаться" + +#: userreference.module:228 +msgid "Invalid user name." +msgstr "Неправильное имя пользователя." + +#: optionwidgets.install:77 +msgid "<div>The allowed values list for %field was updated from </div><pre>%start</pre><div> to </div><pre>%end</pre><div>You can go to the field settings page to give each option a more user-friendly label." +msgstr "<div>Список разрешенных значений для поля %field обновлен от </div><pre>%start</pre><div> до </div><pre>%end</pre><div>Вы можете перейти к странице настроек, чтобы задать для каждой опции более понятные человеку названия." + +#: optionwidgets.install:80 +msgid "<div>The allowed values list for %field was not changed from </div><pre>%start</pre>" +msgstr "<div>Список разрешенных значений для поля %field не обновлен от </div><pre>%start</pre><div> до </div><pre>%end</pre><div>" + +#: nodereference.module:17 +msgid "node reference autocomplete" +msgstr "автозаполнение ссылок на материал" + +#: nodereference.module:42 +msgid "Content types that can be referenced" +msgstr "Типы содержимого, на которые можно ссылаться" + +#: nodereference.module:51 +msgid "Existing Views" +msgstr "Существующие виды" + +#: nodereference.module:56 +msgid "Default Views" +msgstr "Виды по умолчанию" + +#: nodereference.module:61 +msgid "Advanced - Nodes that can be referenced" +msgstr "Дополнительно - Материалы, на которые можно ссылаться" + +#: nodereference.module:64 +msgid "Choose the \"Views module\" view that selects the nodes that can be referenced.<br>Note :<ul><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "Выберите \"Модуль Виды (Views)\" показывает, на какие материалы можно ссылаться.<br>Обратите внимание:<ul><li>Это отменит настройки \"Типы содержимого\" выше. Вместо этого используйте раздел \"фильтры\" видов.</li><li>Используйте раздел \"поля\" для показа дополнительной информации о материалах в форме создания/изменения материалов.</li><li>Используйте раздел \"критерии сортировки\" для определения порядка, в каком материалы будут показаны.</li></ul>" + +#: nodereference.module:280 +msgid "This post can't be referenced." +msgstr "На это сообщение нельзя сослаться." + +#: nodereference.module:283 +msgid "Title mismatch. Please reiterate your selection." +msgstr "Несовпадение названия. Пожалуйста, повторите ваш выбор." + +#: nodereference.module:290 +msgid "No post with that title can be referenced." +msgstr "Нет сообщений с таким название, на которые можно сослаться." + +#: nodereference.module:461 +msgid "<empty>" +msgstr "<пусто>" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.de.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.de.po new file mode 100644 index 0000000000000000000000000000000000000000..8d8e5933a5abfbd90f68f3ce55159e12b15f5469 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.de.po @@ -0,0 +1,97 @@ +# $Id$ +# German translation of CCK +# Copyright 2006 Lukas Gangoly <lukas.gangoly@univie.ac.at> +# Copyright 2006 Jakob Petsovits <jpetso@gmx.at> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 luke +# text.module,v 1.34 2006/06/12 19:59:53 luke +# number.module,v 1.28 2006/05/02 13:52:16 luke +# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke +# content.module,v 1.64 2006/06/12 19:36:54 luke +# nodereference.module,v 1.28 2006/06/12 19:36:54 luke +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke +# userreference.module,v 1.24 2006/05/05 14:10:44 luke +# weburl.module,v 1.8 2006/06/12 19:36:54 luke +# +msgid "" +msgstr "" +"Project-Id-Version: German translation of CCK\n" +"POT-Creation-Date: 2008-11-05 12:54+0100\n" +"PO-Revision-Date: 2008-11-05 13:08+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: theme/content-admin-field-overview-form.tpl.php:11 +msgid "Weight" +msgstr "Reihenfolge" + +#: theme/content-admin-field-overview-form.tpl.php:53 +msgid "Add" +msgstr "Hinzufügen" + +#: theme/content-admin-field-overview-form.tpl.php:59 +msgid "New field" +msgstr "Neues Feld" + +#: theme/content-admin-field-overview-form.tpl.php:72 +msgid "Existing field" +msgstr "Vorhandenes Feld" + +#: theme/content-admin-field-overview-form.tpl.php:84 +msgid "New group" +msgstr "Neue Gruppe" + +#: theme/theme.inc:11 +msgid "Add fields and groups to the content type, and arrange them on content display and input forms." +msgstr "Fügt Felder und Gruppen zu dem Inhaltstyp hinzu und ordnet diese auf der Inhaltsansicht und den Eingabeformularen an." + +#: theme/theme.inc:13 +msgid "You can add a field to a group by dragging it below and to the right of the group." +msgstr "Ein Feld kann einer Gruppe hinzugefügt werden, indem es unterhalb der Zeile dieser Gruppe leicht nach rechts gezogen wird." + +#: theme/theme.inc:16 +msgid "Note: Installing the <a href=\"!adv_help\">Advanced help</a> module will let you access more and better help." +msgstr "Hinweis: Die Installation des <a href=\"!adv_help\">Erweiterte Hilfe</a>-Modul ermöglicht den Zugriff auf weitere und bessere Hilfe." + +#: theme/theme.inc:111 +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "Die Anzeige von Feldern und Bezeichnungen dieses Inhaltstyps konfigurieren, wenn dieser im Anrisstext und ganzseiten Modus angezeigt wird." + +#: theme/theme.inc:114 +msgid "Configure how this content type's fields should be displayed when it's rendered in the following contexts." +msgstr "Die Anzeige von Feldern dieses Inhaltstyps konfigurieren, wenn dieser im folgenden Kontext angezeigt wird." + +#: theme/theme.inc:116 +msgid "Use the 'Exclude' checkbox to exclude an item from the !content value passed to the node template." +msgstr "Das ‚Ausschließen‘-Ankreuzfeld kann verwendet werden, um einen Eintrag aus dem an die Beitragsvorlage übergebenen !content-Wert zu entfernen." + +#~ msgid "Name" +#~ msgstr "Name" +#~ msgid "Type" +#~ msgstr "Typ" +#~ msgid "Operations" +#~ msgstr "Operationen" +#~ msgid "edit" +#~ msgstr "Bearbeiten" +#~ msgid "manage fields" +#~ msgstr "Felder verwalten" +#~ msgid "delete" +#~ msgstr "Löschen" +#~ msgid "No content types available." +#~ msgstr "Keine Inhaltstypen vorhanden." +#~ msgid "» Add a new content type" +#~ msgstr "» Neuen Inhaltstyp hinzufügen" +#~ msgid "Field name" +#~ msgstr "Feldname" +#~ msgid "Field type" +#~ msgstr "Feldtyp" +#~ msgid "Used in" +#~ msgstr "Verwendet in" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.pot b/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.pot new file mode 100644 index 0000000000000000000000000000000000000000..25c7f5563b37d95d0e589aba5ec84af2f8a78a95 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.pot @@ -0,0 +1,65 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (theme) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content-admin-field-overview-form.tpl.php,v 1.1.2.5 2008/10/16 14:40:54 yched +# theme.inc,v 1.1.2.13 2009/04/28 23:06:37 yched +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-06-16 19:00+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: theme/content-admin-field-overview-form.tpl.php:11 +msgid "Weight" +msgstr "" + +#: theme/content-admin-field-overview-form.tpl.php:53 +msgid "Add" +msgstr "" + +#: theme/content-admin-field-overview-form.tpl.php:59 +msgid "New field" +msgstr "" + +#: theme/content-admin-field-overview-form.tpl.php:72 +msgid "Existing field" +msgstr "" + +#: theme/content-admin-field-overview-form.tpl.php:84 +msgid "New group" +msgstr "" + +#: theme/theme.inc:11 +msgid "Add fields and groups to the content type, and arrange them on content display and input forms." +msgstr "" + +#: theme/theme.inc:13 +msgid "You can add a field to a group by dragging it below and to the right of the group." +msgstr "" + +#: theme/theme.inc:16 +msgid "Note: Installing the <a href=\"!adv_help\">Advanced help</a> module will let you access more and better help." +msgstr "" + +#: theme/theme.inc:111 +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "" + +#: theme/theme.inc:114 +msgid "Configure how this content type's fields should be displayed when it's rendered in the following contexts." +msgstr "" + +#: theme/theme.inc:116 +msgid "Use the 'Exclude' checkbox to exclude an item from the !content value passed to the node template." +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.sv.po new file mode 100644 index 0000000000000000000000000000000000000000..4fa11387ce7bed039a7b38377e4526ee57543366 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/theme.sv.po @@ -0,0 +1,66 @@ +# $Id +# +# Swedish translation of Drupal (theme) +# Generated from files: +# content-admin-field-overview-form.tpl.php,v 1.1.2.5 2008/10/16 14:40:54 yched +# theme.inc,v 1.1.2.12 2008/10/28 22:12:09 yched +# +msgid "" +msgstr "" +"Project-Id-Version: CCK - Theme 6.x\n" +"POT-Creation-Date: 2009-03-09 22:08+0100\n" +"PO-Revision-Date: 2009-04-20 21:33+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: theme/content-admin-field-overview-form.tpl.php:11 +msgid "Weight" +msgstr "Vikt" + +#: theme/content-admin-field-overview-form.tpl.php:53 +msgid "Add" +msgstr "Lägg till" + +#: theme/content-admin-field-overview-form.tpl.php:59 +msgid "New field" +msgstr "Nytt fält" + +#: theme/content-admin-field-overview-form.tpl.php:72 +msgid "Existing field" +msgstr "Existerande fält" + +#: theme/content-admin-field-overview-form.tpl.php:84 +msgid "New group" +msgstr "Ny grupp" + +#: theme/theme.inc:11 +msgid "Add fields and groups to the content type, and arrange them on content display and input forms." +msgstr "Lägg till fält och grupper till innehållstypen, och ändra deras disposition vid visning och inmatningsformulär." + +#: theme/theme.inc:13 +msgid "You can add a field to a group by dragging it below and to the right of the group." +msgstr "Du kan lägga till fält till en grupp genom att dra det till platsen under och till höger om gruppen." + +#: theme/theme.inc:16 +msgid "Note: Installing the <a href=\"!adv_help\">Advanced help</a> module will let you access more and better help." +msgstr "Observera: Genom att installera modulen <a href=\"!adv_help\">Advanced help</a> får du tillgång till bättre och mer omfattande hjälp." + +#: theme/theme.inc:111 +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "Ändra inställningarna för hur den här innehållstypens fält och fältetiketter skall visas i sammanfattnings- och fullsidesläge." + +#: theme/theme.inc:114 +msgid "Configure how this content type's fields should be displayed when it's rendered in the following contexts." +msgstr "Ändra inställningarna för hur den här innehållstypens fält skall visas i följande sammanhang." + +#: theme/theme.inc:116 +msgid "Use the 'Exclude' checkbox to exclude an item from the !content value passed to the node template." +msgstr "Använd kryssrutan \"Uteslut\" för att utesluta ett alternativ från värdet !content som skickas till nodmallen." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/uk-ua.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/uk-ua.po new file mode 100644 index 0000000000000000000000000000000000000000..499908372c6dd6fe8eba33456ff896e8ea78b32a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/uk-ua.po @@ -0,0 +1,1754 @@ +# Ukrainian translation of Content Construction Kit (CCK) (all releases) +# Copyright (c) 2009 by the Ukrainian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Content Construction Kit (CCK) (all releases)\n" +"POT-Creation-Date: 2009-10-08 19:18+0000\n" +"PO-Revision-Date: 2009-10-08 22:19+0200\n" +"Language-Team: Ukrainian <podarok@ua.fm>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=((((n%10)==1)&&((n%100)!=11))?(0):(((((n%10)>=2)&&((n%10)<=4))&&(((n%100)<10)||((n%100)>=20)))?(1):2));\n" +"Last-Translator: podarok <podarok@ua.fm>\n" +"X-Poedit-Language: Ukrainian\n" +"X-Poedit-Country: UKRAINE\n" +"X-Poedit-SourceCharset: utf-8\n" + +msgid "CCK" +msgstr "CCK" + +msgid "delete" +msgstr "видалити" + +msgid "Prefix" +msgstr "Префікс" + +msgid "Suffix" +msgstr "Суфікс" + +msgid "Submit" +msgstr "Надіслати" + +msgid "Operations" +msgstr "Дії" + +msgid "Content" +msgstr "Вміст" + +msgid "content" +msgstr "вміст" + +msgid "Groups" +msgstr "Групи" + +msgid "Group" +msgstr "Група" + +msgid "Type" +msgstr "Тип" + +msgid "Cancel" +msgstr "Скасувати" + +msgid "Remove" +msgstr "Вилучити" + +msgid "Description" +msgstr "Опис" + +msgid "Language" +msgstr "Мова" + +msgid "Block title" +msgstr "Назва блоку" + +msgid "Taxonomy" +msgstr "Таксономія" + +msgid "Yes" +msgstr "Так" + +msgid "No" +msgstr "Ні" + +msgid "!date — !username" +msgstr "!date — !username" + +msgid "Content types" +msgstr "Типи матеріалів" + +msgid "Edit" +msgstr "Редагувати" + +msgid "Search" +msgstr "Пошук" + +msgid "None" +msgstr "Жодного" + +msgid "Display settings" +msgstr "Параметри відображення" + +msgid "This action cannot be undone." +msgstr "Цю дію не можна буде скасувати." + +msgid "Number" +msgstr "Число" + +msgid "- None -" +msgstr "- Немає -" + +msgid "Weight" +msgstr "Вага" + +msgid "Help text" +msgstr "Довідковий текст" + +msgid "Types" +msgstr "Типи" + +msgid "Required" +msgstr "Необхідний" + +msgid "none" +msgstr "нічого" + +msgid "Name" +msgstr "Назва" + +msgid "edit" +msgstr "редагувати" + +msgid "Import" +msgstr "Імпорт" + +msgid "Book" +msgstr "Книга" + +msgid "Export" +msgstr "Експорт" + +msgid "Field" +msgstr "Поле" + +msgid "Label" +msgstr "Заголовок" + +msgid "Save" +msgstr "Зберегти" + +msgid "Default" +msgstr "Типовий" + +msgid "Update" +msgstr "Оновити" + +msgid "Add" +msgstr "Додати" + +msgid "remove" +msgstr "видалити" + +msgid "View" +msgstr "Перегляд" + +msgid "Format" +msgstr "Формат" + +msgid "hidden" +msgstr "сховане" + +msgid "Teaser" +msgstr "Анонс" + +msgid "Text" +msgstr "Текст" + +msgid "<none>" +msgstr "<немає>" + +msgid "Content type" +msgstr "Тип вмісту" + +msgid "Continue" +msgstr "Продовжити" + +msgid "Configure" +msgstr "Управління" + +msgid "Node" +msgstr "Матеріал" + +msgid "Include" +msgstr "Включення" + +msgid "Exclude" +msgstr "Виключення" + +msgid "All" +msgstr "Все" + +msgid "Active" +msgstr "Діючий" + +msgid "View arguments" +msgstr "Аргументи вигляду" + +msgid "RSS" +msgstr "RSS" + +msgid "Inline" +msgstr "Вбудоване" + +msgid "Delta" +msgstr "Різниця" + +msgid "Custom" +msgstr "Власний" + +msgid "Poll choices" +msgstr "Варіанти голосів" + +msgid "Content field" +msgstr "Поле матеріалу" + +msgid "Field name" +msgstr "Ім'я поля" + +msgid "Field type" +msgstr "Тип поля" + +msgid "Global settings" +msgstr "Глобальні настройки" + +msgid "Multiple values" +msgstr "" + +msgid "Fields" +msgstr "Поля" + +msgid "Widget type" +msgstr "Тип Візитки" + +msgid "Widget settings" +msgstr "" + +msgid "Contains" +msgstr "Містить" + +msgid "N/A" +msgstr "н/п" + +msgid "configure" +msgstr "налаштувати" + +msgid "Advanced" +msgstr "Додатково" + +msgid "This field is required." +msgstr "Це поле - обов'язкове." + +msgid "Maximum" +msgstr "Найбільше" + +msgid "Scale" +msgstr "Маштаб" + +msgid "Plain text" +msgstr "Чистий текст" + +msgid "Widget" +msgstr "Віджет" + +msgid "Unlimited" +msgstr "Необмежено" + +msgid "Code" +msgstr "Код" + +msgid "General" +msgstr "Загальне" + +msgid "group" +msgstr "група" + +msgid "Basic" +msgstr "Базовий" + +msgid "Filtered text (user selects input format)" +msgstr "Фільтрований текст (користувач обирає вхідний формат)" + +msgid "Text processing" +msgstr "Обробка тексту" + +msgid "Maximum length" +msgstr "Максимальна довжина" + +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "Максимальне значення поля в знаках. Залишіть пустим для необмеженого розміру." + +msgid "%label is longer than %max characters." +msgstr "%label містить більше ніж %max дозволених символів." + +msgid "Rows" +msgstr "Рядки" + +msgid "\"Rows\" must be a positive integer." +msgstr "\"Рядки\" повинні бути додатнім цілим числом." + +msgid "Existing Views" +msgstr "Доступні види" + +msgid "Default Views" +msgstr "Базові види" + +msgid "Empty text" +msgstr "Пустий текст" + +msgid "Order" +msgstr "Замовлення" + +msgid "Integer" +msgstr "Ціле" + +msgid "Edit group" +msgstr "Змінити групу" + +msgid "Add group" +msgstr "Додати групу" + +msgid "Full" +msgstr "Повністю" + +msgid "Size of textfield" +msgstr "Розмір текстового поля" + +msgid "File attachments" +msgstr "Приєднані файли" + +msgid "Show" +msgstr "Показати" + +msgid "Token" +msgstr "Токен" + +msgid "Allowed values list" +msgstr "Список допустимих значень" + +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database and it must match the field storage type, %type. The label is optional and the key will be used as the label if no label is specified." +msgstr "" + +msgid "Select List" +msgstr "Список" + +msgid "Select list" +msgstr "Список" + +msgid "Text field" +msgstr "Текстове поле" + +msgid "body" +msgstr "тіло" + +msgid "PHP code" +msgstr "код PHP" + +msgid "Display fields" +msgstr "Відображення полів" + +msgid "Blocked" +msgstr "Заблоковано" + +msgid "Poll settings" +msgstr "Параметри голосування" + +msgid "Style" +msgstr "Стиль" + +msgid "Your settings have been saved." +msgstr "Ваші параметри збережено" + +msgid "Reversed" +msgstr "" + +msgid "%type settings" +msgstr "Параметри для %type" + +msgid "Menu settings" +msgstr "Налаштування меню" + +msgid "edit " +msgstr "редагування " + +msgid "Illegal value for %name." +msgstr "Недозволене значення %name." + +msgid "<Hidden>" +msgstr "<Приховано>" + +msgid "Comment settings" +msgstr "Налаштування коментарів" + +msgid "Related content" +msgstr "Схожий матеріал" + +msgid "Processing" +msgstr "Обробка" + +msgid "Default value" +msgstr "Базове значення" + +msgid "No content types available." +msgstr "Немає доступних типів матеріалів." + +msgid "Simple" +msgstr "Просте" + +msgid "Above" +msgstr "Над" + +msgid "Number of values" +msgstr "Кількість значень" + +msgid "Warning! Changing this setting after data has been created could result in the loss of data!" +msgstr "Попередження! Зміна цих значень після створення даних можуть призвести до втрат даних!" + +msgid "The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default \"Title\" and \"Body\" may be added. CCK features are accessible through tabs on the <a href=\"@content-types\">content types administration page</a>. (See the <a href=\"@node-help\">node module help page</a> for more information about content types.)" +msgstr "Модуль контенту, обов'язковий компонент Набору побудови контенту (CCK), дозволяє адміністраторам пов'язувати користувацькі поля з типами контенту. В Друпал, типи контенту використовуються для визначення характеристик повідомлення, включаючи заголовок і опис полей, вказаних на сторінках редагування та додавання. Використовуючи модуль контенту (та інші допоміжні модулі в CCK), можна додавати інші користувацькі поля крім полей \"Title\" and \"Body\" за замовчуванням. Можливості CCK доступні через закладки на <a href=\"@content-types\">content types administration page</a>. (Зверніться до <a href=\"@node-help\">node module help page</a> за додатковою інформацією про типи контенту.)" + +msgid "When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a \"person\" may have multiple e-mail addresses) or a single value (i.e., an \"employee\" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules." +msgstr "При доданні користувацького поля до типу контенту ви визначаєте його тип (чи воно буде містити текст, числа чи посилання на інші об'єкти) і те, як воно буде показане (або у вигляді текстового поля, прямокутника з варіантами, відмітками багатозначного чи однозначного вибору, чи автозаповнювальним полем). Поле може мати декілька значень (наприклад, \"person\" може містити декілька адрес електронної пошти) або єдине значення (наприклад, \"employee\" містить один ідентифікаційний номер працівника). Під час додавання та редагування полей, CCK автоматично корегує структуру бази даних за необхідністю. CCK також надає й інші можливості, включаючи інтелектуальне резервування ваших користувацьких даних, модуль імпорту/експорту для визначень типу контенту та інтеграцію з іншими приєднаними модулями." + +msgid "Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href=\"@modules\">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:" +msgstr "Користувацькі типи полів надаються набором додаткових модулів, включених з CCK (кожен модуль підтримує різний тип). <a href=\"@modules\">modules page</a> дозволяє вам вмикати та вимикати складові CCK. Стандартне встановлення CCK включає в себе:" + +msgid "<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available." +msgstr "<em>number</em>, що додає числові типи полей, у цілій, дробній чи з плаваючою комою формі чисел. Ви можете визначити набір дозволених даних для введення, або вказати допустимий окіл значень. В асортименті є набір звичайних форматів для показу числових даних." + +msgid "<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values." +msgstr "<em>text</em>, що додає текстові типи полей. Текстове поле може містити лише простий текст, або, за бажанням, може використовувати фільтри формату вводу Drupal'у для безпечної роботи з введенням збагаченого тексту. Поля введення текту можуть бути у вигляді одної строки, декількох строк (текстового поля), або для більшого контролю, прямокутника з варіантами, відмітками багатозначного чи однозначного вибору. За бажанням, CCK може звірювати введене з набором дозволених значень" + +msgid "<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple \"employee\" nodes may contain a <em>nodereference</em> field linking to an \"employer\" node)." +msgstr "<em>nodereference</em>, що створює користувацькі посилання між вузлами Drupal. Наприклад, додаючи поле <em>nodereference</em> і два різних типа контенту, ви можете з легкістю створювати складні спадкові стосунки між даними (декілька вузлів \"employee\" можуть містити поле <em>nodereference</em>, що пов'язує їх з вузлом \"employer\")." + +msgid "<em>userreference</em>, which creates custom references to your sites' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site's users and posts. To track user involvement in a post beyond Drupal's standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named \"Edited by\" to a content type to store a link to an editor's user account page." +msgstr "<em>userreference</em>, що створює користувацькі посилання на рахунки користувачів вашого сайту. Додаючи поле <em>userreference</em>, ви можете створювати складні взаємозв'зки між користувачами та повідомленнями вашого сайту. Наприклад, для відслідковування участі користувачів у повідомленні понад стандартного поля Drupal <em>Authored by</em>, додайте поле <em>userreference</em> з назвою \"Edited by\" до типу контенту, щоб зберегти посилання на сторінку рахунку редактора повідомлення." + +msgid "<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module." +msgstr "<em>fieldgroup</em>, що створює розбірні набори полів для фіксування групи пов'язаних полів. Набір полів може бути відкритим чи закритим за замовчуванням. Порядок ваших наборів полів, а також порядок полів в наборі, управляється через перетягування у інтерфейсі, наданому модулем контенту." + +msgid "For more information, see the online handbook entry for <a href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK project page</a>." +msgstr "Для додаткової інформації читайте розділ довідника <a href=\"@handbook-cck\">CCK</a> на сторінці <a href=\"@project-cck\">CCK проекту</a>." + +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "Налаштувати те, як поля цього типу контенту та мітки полів повинні бути показані в режимах короткого та повного перегляду." + +msgid "Configure how this content type's fields should be displayed when it's rendered in the following contexts." +msgstr "Налаштувати те, як поля цього типу контенту повинні бути показані під час обробки в наступних контекстах." + +msgid "Control the order of fields in the input form." +msgstr "Налаштування послідовності полів у формі вводу." + +msgid "!title: !required" +msgstr "!title: !required" + +msgid "Add another item" +msgstr "Додати інший елемент" + +msgid "Full node" +msgstr "Повний матеріал" + +msgid "RSS Item" +msgstr "" + +msgid "Search Index" +msgstr "База пошуку" + +msgid "Search Result" +msgstr "Результат пошуку" + +msgid "Updating field type %type with module %module." +msgstr "Оновлення типу поля %type модулем %module." + +msgid "Updating widget type %type with module %module." +msgstr "Оновлення типу Візитки %type модулем %module." + +msgid "Manage fields" +msgstr "Керувати полями" + +msgid "Add field" +msgstr "Додати поле" + +msgid "Remove field" +msgstr "Видалення поля" + +msgid "Allows administrators to define new content types." +msgstr "Дозволяє адміністраторам задавати новий тип матеріалу" + +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Лише для досвідчених користувачів: код PHP, що видає відповідний набір дозволених значень. Не повинен включати розмежовувачів <?php ?>. Якщо це поле заповнене, набір, виданий цім кодом, замістить вищевказаний перелік дозволених значень." + +msgid "Trimmed" +msgstr "Скорочене" + +msgid "Text area" +msgstr "Текстове поле" + +msgid "Used in" +msgstr "Використано в" + +msgid "No fields have been defined for any content type yet." +msgstr "Жодних полів ще не задано для жодного типу матеріалів" + +msgid "There are no fields configured for this content type. You can !link." +msgstr "Немає полів налаштованих на використання в цьому типі контенту. Ви можете !link." + +msgid "Add a new field" +msgstr "Додати нове поле" + +msgid "To change the order of a field, grab a drag-and-drop handle under the Label column and drag the field to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the Save button at the bottom of the page." +msgstr "" + +msgid "no styling" +msgstr "без стилю" + +msgid "simple" +msgstr "просто" + +msgid "fieldset" +msgstr "група полів" + +msgid "fieldset - collapsible" +msgstr "група полів - здатна звертатись" + +msgid "fieldset - collapsed" +msgstr "група полів - звернута" + +msgid "Add existing field" +msgstr "" + +msgid "Create new field" +msgstr "Створити нове поле" + +msgid "The machine-readable name of the field. This name cannot be changed later! The name will be prefixed with 'field_' and can include lowercase unaccented letters, numbers, and underscores. You'll be able to choose a human-readable label for the field on next page." +msgstr "Системна назва поля. Цю назву <strong>неможна</strong> буде змінити згодом! До назви буде додано префікс 'field_'. Назва може містити прописні ненаголошені букви латинського алфавіту, цифри та символи нижнього підкреслення. Ви будете мати можливість ввести назву поля, яка буде відображатися для користувачів, на наступній сторінці." + +msgid "No field modules are enabled. You need to <a href=\"!modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "" + +msgid "Choose the type of value to store and an input method from the list below." +msgstr "" + +msgid "Added field %label." +msgstr "Додано поле %label" + +msgid "There was a problem adding field %label." +msgstr "Виникла проблема додавання поля %label." + +msgid "The field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Назва поля %field_name неправильна. Назва може містити прописні ненаголошені букви латинського алфавіту, цифри та символи нижнього підкреслення." + +msgid "The field name %field_name already exists." +msgstr "Назва поля %field_name вже існує." + +msgid "The name 'field_instance' is a reserved name." +msgstr "Назва 'field_instance' зарезервована." + +msgid "Created field %label." +msgstr "Створити поле %label." + +msgid "There was a problem creating field %label." +msgstr "Виникла проблема створення поля %label." + +msgid "Are you sure you want to remove the field %field?" +msgstr "Ви впевнені, що хочете видалити поле %field?" + +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Якщо в даному полі знаходиться якийсь матеріал - він буде втрачений. Це незворотня операція" + +msgid "Removed field %field from %type." +msgstr "Видалено поле %field із %type." + +msgid "There was a problem deleting %field from %type." +msgstr "Виникла проблема видалення %field із %type." + +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Ці параметри застосовуються тільки до поля %field так як знаходиться в типі матеріалу %type" + +msgid "Instructions to present to the user below this field on the editing form." +msgstr "" + +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format :<pre>!sample</pre>Using !link_devel's 'devel load' tab on a %type content page might help you figure out the expected format." +msgstr "" + +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Ці параметри застосовуються до поля %field в кожному типі матеріалів, в якому воно використовуються." + +msgid "Select a specific number of values for this field, or 'Unlimited' to provide an 'Add more' button so the users can add as many values as they like." +msgstr "" + +msgid "Save field settings" +msgstr "Збереження параметрів поля" + +msgid "The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value" +msgstr "Код PHP значення за замовчуванням видав неправильне значення.<br/>Очікуваний формат: <pre>!sample</pre> Видане значення: @value" + +msgid "The default value PHP code created @value which is invalid." +msgstr "" + +msgid "The default value is invalid." +msgstr "Базове значення некоректне" + +msgid "Saved field %label." +msgstr "Збережено поле %label" + +msgid "The update has encountered an error." +msgstr "Оновлення викликало помилку" + +msgid "The database has been altered and data has been migrated or deleted." +msgstr "База даних змінена і дані переміщено або видалено." + +msgid "An error occurred and database alteration did not complete." +msgstr "Виникла помилка і зміни в базі даних незавершені." + +msgid "Processing %title" +msgstr "Обробка %title" + +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "вдало оброблено @count елемент:" +msgstr[1] "вдало оброблено @count елементи:" +msgstr[2] "вдало оброблено @count елементів:" + +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "Таблиця %old_name полей матеріалу була перейменована в %new_name і елементи полей були оновлені" + +msgid "The content fields table %name has been deleted." +msgstr "Таблиця %name полей матеріалу була видалена" + +msgid "Add another !field value" +msgstr "Додати інше значення !field" + +msgid "If the amount of boxes above isn't enough, click here to add more items." +msgstr "" + +msgid "Referenced node ID" +msgstr "ID пов'язаного матеріалу" + +msgid "Referenced node title" +msgstr "Заголовок пов'язаного матеріалу" + +msgid "Formatted HTML link to the node" +msgstr "" + +msgid "Raw number value" +msgstr "Чисте значення номера" + +msgid "Formatted number value" +msgstr "Форматоване значення номера" + +msgid "Raw, unfiltered text" +msgstr "Чистий, нефільтрований текст" + +msgid "Formatted and filtered text" +msgstr "Форматований і фільтрований текст" + +msgid "Referenced user ID" +msgstr "ID пов'язаного користувача" + +msgid "Referenced user name" +msgstr "Ім'я пов'язаного користувача" + +msgid "Formatted HTML link to referenced user" +msgstr "Форматоване HTML посилання до пов'язаного користувача" + +msgid "Appears in : @types" +msgstr "З'являється в : @types" + +msgid "Group multiple values" +msgstr "Багато значень групи" + +msgid " values," +msgstr " значення," + +msgid "Starting from" +msgstr "Починати з" + +msgid "Start from last values" +msgstr "Починати з останнього значення" + +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "Ця форма обробить тип контенту та одне або декілька полів цього типу, та експортує налаштування. Експортування, створене цим процесом, можна копіювати та вставляти як імпортування у поточну або будь-яку іншу базу даних. Імпортування додасть поля в існуючий тип контенту або створить новий тип контенту, що включає обрані поля." + +msgid "Select the content type to export." +msgstr "Вибір типу матеріалу для вивантаження" + +msgid "Select the group definitions to export from %type." +msgstr "" + +msgid "Select the field definitions to export from %type." +msgstr "" + +msgid "Export data" +msgstr "Вивантаження даних" + +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Скопіюйте текст експорту та вставте його в інший тип контенту, використовуючи функцію імпорту." + +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "Ця форма імпортує визначення полів, експортовані з іншого типу контенту або іншої бази даних. <br/>Зверніть увагу, що поля не можна копіювати всередині одного типу контенту, так що імпортовані поля будуть додані лише у тому випадку, якщо вони ще не існують в обраному типу." + +msgid "<Create>" +msgstr "<Створення>" + +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Оберіть тип контенту для імпортування вказаних полів. <br/>Оберіть <Create> для створення нового типу контенту для вміщення полів." + +msgid "Import data" +msgstr "Втягування даних" + +msgid "Paste the text created by a content export into this field." +msgstr "Вставте текст, створений експортуванням контенту, у це поле." + +msgid "The import data is not valid import text." +msgstr "Дані для втягування не є коректними" + +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "Наступні модулі слід включити для роботи цього імпортування: %modules." + +msgid "<create>" +msgstr "<Створення>" + +msgid "The content type %type already exists in this database." +msgstr "Тип матеріалу %type вже міститься в базі даних." + +msgid "Exiting. No import performed." +msgstr "Вихід. Не виконано втягування;" + +msgid "An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Трапилась помилка при доданні типу контенту %type.<br/>Будь ласка, прогляньте вказані помилки для докладних деталей." + +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "Втягнуте поле %field_label (%field_name) не було додано до %type через те, що поле вже існує в %type." + +msgid "The field %field_label (%field_name) was added to the content type %type." +msgstr "Поле %field_label (%field_name) додано до типу матеріалів %type." + +msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'." +msgstr "Трапилась помилка при експортуванні даних 'показу налаштувань' для поля %field_name.<br/> Помилка бази даних наступна: '%db_err'." + +msgid "Content Copy" +msgstr "Копіювання матеріалів" + +msgid "Enables ability to import/export field definitions." +msgstr "Включає здатність імпортувати/експортувати визначення полей." + +msgid "field_name" +msgstr "ім'я поля" + +msgid "view " +msgstr "вигляд " + +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "Будь ласка негайно <a href=\"!url\">configure your field permissions</a>. Всі поля за замовчуванням недоступні." + +msgid "Content Permissions" +msgstr "Доступи до матеріалів" + +msgid "Set field-level permissions for CCK fields." +msgstr "Встановіть дозволи рівнів полей для полей CCK." + +msgid "These settings apply to the group in the node editing form." +msgstr "Ці параметри використовувати до групи в формі редагування матеріалу" + +msgid "always open" +msgstr "завжди відкрите" + +msgid "collapsible" +msgstr "можливість звертання" + +msgid "collapsed" +msgstr "звернуто" + +msgid "Instructions to present to the user on the editing form." +msgstr "Інструкції, що відображаються користувачу на формі редагування" + +msgid "These settings apply to the group on node display." +msgstr "Ці налаштування стосуються групи на екрані вузлів." + +msgid "A description of the group." +msgstr "Опис групи" + +msgid "The group name %name already exists." +msgstr "Назва групи %name вже існує." + +msgid "The group name %name is invalid." +msgstr "Назва групи %name неправильна." + +msgid "Are you sure you want to remove the group %label?" +msgstr "Ви впевнені, що хочете видалити групу %label?" + +msgid "The group %group_name has been removed." +msgstr "Групу %label видалено" + +msgid "Display in group" +msgstr "Відображати в групі" + +msgid "Select a group, in which the field will be displayed on the editing form." +msgstr "" + +msgid "Fieldgroup" +msgstr "Група полів" + +msgid "Create field groups for CCK fields." +msgstr "Створити групи для для CCK полів" + +msgid "Node reference" +msgstr "Посилання на матеріал" + +msgid "Store the ID of a related node as an integer value." +msgstr "Зберегти ІН пов'язаного вузлу цілим числом." + +msgid "Content types that can be referenced" +msgstr "Типи контенту, що мона ввести в довідку" + +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Розширене - вузли, що можна внести в довідку (Переглянути)" + +msgid "Choose the \"Views module\" view that selects the nodes that can be referenced.<br>Note :<ul><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "" + +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Надайте перелік аргументів, розділений комами, для передачи на перегляд." + +msgid "%name : This post can't be referenced." +msgstr "" + +msgid "Title (link)" +msgstr "Назва(посилання)" + +msgid "Title (no link)" +msgstr "Назва(без посилання)" + +msgid "Autocomplete text field" +msgstr "Текстове поле автозаповнення" + +msgid "%name: Title mismatch. Please check your selection." +msgstr "" + +msgid "Nodereference autocomplete" +msgstr "Автодоповнення посилання на матеріал" + +msgid "Node Reference" +msgstr "Посилання на матеріал" + +msgid "Defines a field type for referencing one node from another." +msgstr "визначає тип поля для відрізняння одного вузла від іншого." + +msgid "Store a number in the database as an integer." +msgstr "Зберегти як ціле число в базі даних." + +msgid "Decimal" +msgstr "Десяткове" + +msgid "Store a number in the database in a fixed decimal format." +msgstr "Зберегти як фіксоване дробне число в базі даних." + +msgid "Float" +msgstr "Плаваюче" + +msgid "Store a number in the database in a floating point format." +msgstr "Зберегти як число з плаваючою комою в базі даних." + +msgid "Minimum" +msgstr "Найменше" + +msgid "Precision" +msgstr "Точність" + +msgid "The total number of digits to store in the database, including those to the right of the decimal." +msgstr "Загальне число цифр для збереження в базі даних, включаючи ті, що справа від знаку дробу." + +msgid "The number of digits to the right of the decimal." +msgstr "Кількість цифр справа від знаку дробу." + +msgid "Decimal marker" +msgstr "Десятковий розділювач" + +msgid "The character users will input to mark the decimal point in forms." +msgstr "Знак, який користувачі введуть для відмічення знаку дробу у формах." + +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Визначіть строку-префікс для значення, наприклад $ або €. Залишіть пустим для нічого. Розділіть значення однини та множини знаком | (фунт|фунти)." + +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Визначіть строку-суфікс для значення, наприклад m², m/s², kb/s. Залишіть пустим для нічого. Розділіть значення однини та множини знаком | (фунт|фунти)." + +msgid "Allowed values" +msgstr "Дозволені значення" + +msgid "\"Minimum\" must be a number." +msgstr "\"Найменше\" повинно бути числом." + +msgid "\"Maximum\" must be a number." +msgstr "\"Найбільше\" повинно бути числом" + +msgid "The value of %name may be no smaller than %min." +msgstr "%name: значення повинно бути не меншим чим %min." + +msgid "The value of %name may be no larger than %max." +msgstr "%name: значення повинно бути не більшим чим %max." + +msgid "unformatted" +msgstr "неформатоване" + +msgid "Only numbers and decimals are allowed in %field. %start was changed to %value." +msgstr "" + +msgid "Only numbers are allowed in %field. %start was changed to %value." +msgstr "" + +msgid "Only numbers and the decimal character (%decimal) are allowed in %field. %start was changed to %value." +msgstr "" + +msgid "Defines numeric field types." +msgstr "Зазначення числових типів полей" + +msgid "Create a list of options as a list in <strong>Allowed values</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "" + +msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "Для віджету 'один прямокутник з варіантами ввімнути/вимкнути' визначіть спочатку значення 'вимкнути', а потім значення 'ввімкнути' у розділі <strong>Allowed values</strong>. Зверніт увагу, прямокутник буде помічено міткою значення 'ввімкнути'." + +msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "Віджет 'прямокутники з варіантами' буде показувати багатоваріантний вибір, якщо ця опція обрана для цього поля, інакше буде вказано одноваріантний вибір." + +msgid "Check boxes/radio buttons" +msgstr "Відмітьте квадратики/кнопки" + +msgid "Single on/off checkbox" +msgstr "Одиночна опція так/ні" + +msgid "Option Widgets" +msgstr "Спецдодатки" + +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "Визначає віджети вибору та прямокутників з варіантами для текстових та числових полей." + +msgid "Store text in the database." +msgstr "Збереження тексту в базі даних" + +msgid "Text area (multiple rows)" +msgstr "Текстове поле (багаторядкове)" + +msgid "Defines simple text field types." +msgstr "Надання простих текстових типів полів" + +msgid "User reference" +msgstr "Посилання на користувача" + +msgid "Store the ID of a related user as an integer value." +msgstr "Збереження ID пов'язаного користувача як ціле значення" + +msgid "User roles that can be referenced" +msgstr "Ролі користувачів можуть бути пов'язані" + +msgid "User status that can be referenced" +msgstr "Статус користувача може бути пов'язаний" + +msgid "%name: Invalid user." +msgstr "" + +msgid "Reverse link" +msgstr "Зворотнє посилання" + +msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record." +msgstr "При обранні, буде показано обернене посилання на вузол довідки на запису внесеного користувача." + +msgid "Userreference autocomplete" +msgstr "Автозаповнення довідки користувачів" + +msgid "User Reference" +msgstr "Посилання на користувача" + +msgid "Defines a field type for referencing a user from a node." +msgstr "Визначає тип поля для знаходження користувача з вузла." + +msgid "node reference autocomplete" +msgstr "" + +msgid "Autocomplete Text Field" +msgstr "" + +msgid "%name : Title mismatch. Please check your selection." +msgstr "" + +msgid "<empty>" +msgstr "<пусто>" + +msgid "Text Field" +msgstr "" + +msgid "Node context" +msgstr "Вміст матеріалу" + +msgid "Print" +msgstr "Друк" + +msgid "Locked" +msgstr "Заблоковано" + +msgid "Create field" +msgstr "" + +msgid "No group" +msgstr "" + +msgid "No fields have been added to this group." +msgstr "" + +msgid "!label (!name)" +msgstr "!label (!name)" + +msgid "Updated field groups." +msgstr "" + +msgid "Updated field weights." +msgstr "" + +msgid "Data settings" +msgstr "" + +msgid "There are no groups configured for this content type." +msgstr "" + +msgid "There are no fields configured for this content type." +msgstr "" + +msgid "Updated group weights." +msgstr "" + +msgid "The machine-readable name of the field.<br/>Allowed characters : unaccentuated a-z, numbers and _. All other characters will be discarded.<br/>You'll be able to choose a human-readable label for the field on next page" +msgstr "" + +msgid "The field name %field_name is invalid." +msgstr "" + +msgid "Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags" +msgstr "Інструкції, що відобразяться користувачу нижче цього поля на формі редагування. <br />Дозволені HTML теги: @tags" + +msgid "Advanced Usage Only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format :<pre>!sample</pre>Using !link_devel 'devel load' tab on a %type content page might help you figure out the expected format." +msgstr "" + +msgid "<none>" +msgstr "<нема>" + +msgid "You're not allowed to input PHP code." +msgstr "Вам недозволено ввожити PHP код" + +msgid "This PHP code was set by an administrator and will override any value specified above." +msgstr "Код PHP був встановлений адміністратором і буде перезаписувати будь-які значенн, вказані вище" + +msgid "The default value PHP code returned an incorrect value<br/>Expected format : <pre>!sample</pre>Returned value : @value" +msgstr "" + +msgid "Saved field %field." +msgstr "" + +msgid "No PostgreSQL mapping found for %type data type." +msgstr "" + +msgid "database" +msgstr "" + +msgid "The content fields table %name has been created." +msgstr "" + +msgid "A content field from the referenced node." +msgstr "Поле матеріалу з пов'язаного матеріалу" + +msgid "Configure how the label is going to be displayed" +msgstr "" + +msgid "Field / Formatter" +msgstr "Поле / Форматувальник" + +msgid "Select a field and formatter." +msgstr "Оберіть поле і форматувальник" + +msgid "\"@s\" field @name" +msgstr "\"@s\" поле @name" + +msgid "Do not group multiple values" +msgstr "" + +msgid "Show first value only" +msgstr "" + +msgid "Show last value only" +msgstr "" + +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "Використання PHP для параметрів поля (небезпечно - використовуйте з обережністю)" + +msgid "A file has been pre-loaded for import." +msgstr "Файл для втягування завантажено" + +msgid "An error has occured adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "" + +msgid "An error has occured adding the field %field_label (%field_name).<br/>Please check the errors displayed for more details." +msgstr "" + +msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field settings.<br/>Please check the errors displayed for more details." +msgstr "" + +msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field's 'display_settings'.<br/>The db error is: '%db_err'." +msgstr "" + +msgid "These settings apply to the group in the node editing form" +msgstr "" + +msgid "Content fieldgroup" +msgstr "Група полей матеріалу" + +msgid "Content fieldgroup content goes here." +msgstr "" + +msgid "All fields from a fieldgroup on the referenced node." +msgstr "Всі поля з групи полей на вказаному вузлі." + +msgid "Text to display if group has no data. Note that title will not display unless overridden." +msgstr "Текст для показу у випадку, коли у групі нема даних. Відмітьте, що заголовок не буде показано, хіба що не відбудетья відміна." + +msgid "\"@s\" fieldgroup @name" +msgstr "\"@s\" група полей @name" + +msgid "%name: Found no valid post with that title." +msgstr "" + +msgid "Node from reference" +msgstr "" + +msgid "Adds a node from a node reference in a node context; if multiple nodes are referenced, this will get the first referenced node only." +msgstr "" + +msgid "Node reference field" +msgstr "" + +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds). " +msgstr "" + +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "Можливі значення цього поля. Введіть по одному значенню на строку, в форматі ключ|мітка. Ключ - значення, що буде збережене в базі даних, і воно має співпадати з типом збереження поля (%type). Мітка необов'язкова, і ключ буде використано замість неї, якщо вона не вказана.<br /> Дозволені мітки HTML: @tags" + +msgid "Advanced Usage Only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "" + +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "Цей код PHP був встановлений адміністратором і замістить вищевказаний перелік дозволених значень." + +msgid "Create a list of options as a list in <strong>Allowed values</strong> or as an array in PHP code at the bottom of this page. These values will be the same for the %field in all content types. " +msgstr "" + +msgid "For a 'Single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "" + +msgid "The 'Checkboxes / radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "" + +msgid "Set the option to the number of initial characters to filter by. Leave empty for full term; use 1 for an A/B/C style glossary." +msgstr "" + +msgid "user reference autocomplete" +msgstr "" + +msgid "%name : Invalid user." +msgstr "" + +msgid "Reverse Link" +msgstr "" + +msgid "Related Content" +msgstr "" + +msgid "User from reference" +msgstr "" + +msgid "Adds a user from a user reference in a node context; if multiple users are referenced, this will get the first referenced user only." +msgstr "" + +msgid "User reference field" +msgstr "" + +msgid "<div>The allowed values list for %field was updated from </div><pre>%start</pre><div> to </div><pre>%end</pre><div>You can go to the field settings page to give each option a more user-friendly label." +msgstr "" + +msgid "<div>The allowed values list for %field was not changed from </div><pre>%start</pre>" +msgstr "" + +msgid "Show @count value(s)" +msgstr "Відображення @count значень" + +msgid "starting from @count" +msgstr "починаючи з @count" + +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Дозволені значення" + +msgid "%name: illegal value." +msgstr "%name: значення некоректне." + +msgid "%name: the value may not be longer than %max characters." +msgstr "%name: значення не може бути довшим чим %max символів" + +msgid "Autocomplete matching" +msgstr "Порівняння автозаповнення" + +msgid "Starts with" +msgstr "Починається з" + +msgid "Load a referenced user" +msgstr "Завантажити згаданого користувача" + +msgid "Content containing the user reference field" +msgstr "Матеріал містить поле пов'язаного користувача" + +msgid "Referenced user" +msgstr "Згаданий користувач" + +msgid "Load a referenced node" +msgstr "Завантаження пов'язаного матеріалу" + +msgid "Content containing the node reference field" +msgstr "Контент, що містить поле довідки вузлу" + +msgid "Referenced content" +msgstr "Пов'язаний матеріал" + +msgid "Populate a field" +msgstr "Заповнення поля" + +msgid "Select the machine-name of the field." +msgstr "Вибір комп'ютерного імені поля" + +msgid "Revision information" +msgstr "Інформація про зміни" + +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users." +msgstr "Оберіть метод збору підказок щодо автозаповнення. Зверніть увагу, що <em>Contains</em> може призвести до проблем з продуктивністю на сайтах з тисячами вузлів." + +msgid "View used to select the nodes" +msgstr "Перегляд для вибору вузлів" + +msgid "%name: this post can't be referenced." +msgstr "%name: Це повідомлення не можна внести в довідку." + +msgid "Node module form." +msgstr "Форма модуля матеріалу" + +msgid "Locale module form." +msgstr "Форма модуля перекладів" + +msgid "Taxonomy module form." +msgstr "Форма модуля таксономії" + +msgid "Poll title" +msgstr "Назва Голосування" + +msgid "'@column' => value for @column" +msgstr "'@column' => значення для @column" + +msgid "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" +msgstr "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" + +msgid "Create a list of options as a list in <strong>Allowed values list</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "Створіть перелік опцій в формі <strong>Allowed values list</strong> або як набір в коді PHP. Ці значення будуть однаковими для %field у всіх типах контенту." + +msgid "You need to specify the 'allowed values' for this field." +msgstr "Необхідно задавати 'дозвроені значення' для цього поля" + +msgid "Change basic information" +msgstr "Зміна базової інформації" + +msgid "Fieldset" +msgstr "Набір полей" + +msgid "Translation settings" +msgstr "Параметри Перекладу" + +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes." +msgstr "Оберіть метод пошуку підказок автозаповнення. Зверніть увагу, що <em>Contains</em> може призвести до проблем з продуктивністю на сайтах з тисячами вузлів." + +msgid "%name: title mismatch. Please check your selection." +msgstr "%name: неспівпадіння заголовку. Будь ласка, провірте ваш вибір." + +msgid "Path settings" +msgstr "" + +msgid "%name: the value may be no smaller than %min." +msgstr "%name: значення повинно бути не меншим чим %min." + +msgid "%name: the value may be no larger than %max." +msgstr "%name: значення повинно бути не більшим чим %max." + +msgid "%name: found no valid user with that name." +msgstr "%name: не знайдено дійсного користувача з таким ім'ям." + +msgid "Field label" +msgstr "" + +msgid "Form settings" +msgstr "Параметри форми" + +msgid "Type of group." +msgstr "Тип групи" + +msgid "%name: this field cannot hold more that @count values." +msgstr "%name: це поле не може отримати більше чим @count значень." + +msgid "If unchecked, each item in the field will create a new row, which may appear to cause duplicates. This setting is not compatible with click-sorting in table displays." +msgstr "Якщо не обрано, кожен елемент поля буде створювати новий рядок, що може привести до дублів. Ці параметри несумісні з сортуванням таблиць при кліках на відображенні." + +msgid "Some updates are still pending. Please return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Деякі оновлення все ще в черзі. Прохання повернутись до <a href=\"@update-php\">update.php</a> і запустити необхідні оновлення" + +msgid "Some updates are still pending.<br/>Please re-run the update script." +msgstr "Деякі оновлення ще знаходяться в черзі. <br/>Будь ласка, заново запустіть скрипт оновлення." + +msgid "Comment module form." +msgstr "" + +msgid "Translation module form." +msgstr "" + +msgid "Menu module form." +msgstr "Форма модуля меню" + +msgid "Book module form." +msgstr "Форма модуля Книг" + +msgid "Path module form." +msgstr "" + +msgid "Poll module title." +msgstr "Назва модуля голосувань" + +msgid "Poll module choices." +msgstr "Варіанти модуля голосувань" + +msgid "Poll module settings." +msgstr "Параметри модуля голосувань" + +msgid "Upload module form." +msgstr "форма модуля Завантажень" + +msgid "Updates for CCK-related modules are not run until the modules are enabled on the <a href=\"@admin-modules-path\">administer modules page</a>. When you enable them, you'll need to return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Оновлення для модулів, пов'язаних з CCK, не відбуваються до включення модулів на <a href=\"@admin-modules-path\">administer modules page</a>. Коли ви включите їх, вам слід повернутись до <a href=\"@update-php\">update.php</a> і провести оновлення, що залишились." + +msgid "!module.module has updates but cannot be updated because content.module is not enabled.<br />If and when content.module is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "!module.module має оновлення, але не може їх розпочати з-за відключення content.module. <br />Якщо і коли content.module буде включено, вам потрібно буде повторно запустити скрипт оновлення. Ви будете й надалі бачити це повідомлення, аж поки модуль не буде включено і оновлення пройдені." + +msgid "!module.module has updates and is available in the modules folder but is not enabled.<br />If and when it is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "!module.module має оновлення і доступний в папці модулів, але він не включений. <br />Якщо і коли його буде включено, вам потрібно буде повторно запустити скрипт оновлення. Ви будете й надалі бачити це повідомлення, аж поки модуль не буде включено і оновлення пройдені." + +msgid "CCK - No Views integration" +msgstr "CCK - без інтеграції з Виглядама" + +msgid "CCK integration with Views module requires Views 6.x-2.0-rc2 or greater." +msgstr "CCK - інтеграція з Виглядама потребує Views 6.x-2.0-rc2 або новіше" + +msgid "manage fields" +msgstr "керування полями" + +msgid "» Add a new content type" +msgstr "» Додавання нового типу матеріалу" + +msgid "@field_name (Locked)" +msgstr "@field_name (Заблоковано)" + +msgid "This content type has inactive fields. Inactive fields are not included in lists of available fields until their modules are enabled." +msgstr "Цей тип матеріалу має неактивні поля. Неактивні поля не включені в список доступних до моменту вмикання їхніх модулів" + +msgid "!field (!field_name) is an inactive !field_type field that uses a !widget_type widget." +msgstr "!field (!field_name) неактивне поле !field_type що використовує Візитку !widget_type." + +msgid "- Select a field type -" +msgstr "- Вибір типу поля -" + +msgid "- Select a widget -" +msgstr "- Вибір widget -" + +msgid "Field name (a-z, 0-9, _)" +msgstr "Ім'я поля (a-z, 0-9, _)" + +msgid "Type of data to store." +msgstr "Тип даних для збереження" + +msgid "Form element to edit the data." +msgstr "Елемент форми для зміни даних" + +msgid "- Select an existing field -" +msgstr "- Вибір наявного поля -" + +msgid "Field to share" +msgstr "Поле для відображення" + +msgid "Group name (a-z, 0-9, _)" +msgstr "Ім'я групи (a-z, 0-9, _)" + +msgid "Add new field: you need to provide a label." +msgstr "Додавання нового поля: Вам потрібно вказати мітку" + +msgid "Add new field: you need to provide a field name." +msgstr "Додавання нового поля: Вам потрібно вказати ім'я поля" + +msgid "Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Додавання нового поля: ім'я поля %field_name - некоректне. Ім'я повинно включати лише латинські символи, цифри і підкреслення" + +msgid "Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix." +msgstr "Додавання нового поля: ім'я поля %field_name надто довге. Ім'я обмежено 32 символами, включаючи префікс 'field_'" + +msgid "Add new field: the name 'field_instance' is a reserved name." +msgstr "Додавання нового поля: ім'я 'field_instance' - зарезервовано" + +msgid "Add new field: the field name %field_name already exists." +msgstr "Додавання нового поля: ім'я поля %field_name зайняте" + +msgid "Add new field: you need to select a field type." +msgstr "Додавання нового поля: потрібно обрати тип поля" + +msgid "Add new field: you need to select a widget." +msgstr "Додавання нового поля: вам потрібно обрати візитку" + +msgid "Add new field: invalid widget." +msgstr "Додавання нового поля: некоректна візитка" + +msgid "Add existing field: you need to provide a label." +msgstr "Існуюче поле: Вам потрібно вказати мітку" + +msgid "Add existing field: you need to select a field." +msgstr "Існуюче поле: Вам потрібно обрати поле" + +msgid "Add existing field: you need to select a widget." +msgstr "Існуюче поле: Вам потрібно обрати візитку" + +msgid "Add existing field: invalid widget." +msgstr "Існуюче поле: некоректна візитка" + +msgid "The field %label cannot be added to a content type because it is locked." +msgstr "Поле %label неможливо додати бо тип матеріалу заблокований" + +msgid "There are no fields configured for this content type. You can add new fields on the <a href=\"@link\">Manage fields</a> page." +msgstr "Відсутні поля для даного типу матеріалів. Ви можете додавати нові поля на сторінці <a href=\"@link\">Керування полями</a>" + +msgid "@type: @field (@label)" +msgstr "@type: @field (@label)" + +msgid "Edit basic information" +msgstr "Зміна базової інформації" + +msgid "The machine-readable name of the field. This name cannot be changed." +msgstr "Комп'ютерне ім'я поля. Змінити неможливо" + +msgid "A human-readable name to be used as the label for this field in the %type content type." +msgstr "Людиноподібне ім'я, що буде використано як мітка для цього поля в типі матеріалу %type" + +msgid "The type of data you would like to store in the database with this field. This option cannot be changed." +msgstr "Тип даних, що бажаєте зберігати в базі даних з допомогою цього поля. Дана операція не може бути змінена." + +msgid "The type of form element you would like to present to the user when creating this field in the %type content type." +msgstr "Тип елемента форми, що хочете відобразити користувачу, коли створюється це поле в типі матеріалу %type" + +msgid "Updated basic settings for field %label." +msgstr "Оновлено базові параметри для поля %label." + +msgid "There was a problem updating the basic settings for field %label." +msgstr "Виникла проблема оновлення базових параметрів для поля %label." + +msgid "This field is <strong>locked</strong> and cannot be removed." +msgstr "Поле <strong>заблоковане</strong> і не може бути видалене" + +msgid "The field %field is locked and cannot be edited." +msgstr "Поле %field заблоковане і не може бути зміненим" + +msgid "%type basic information" +msgstr "%type базова інформація" + +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>To figure out the expected format, you can use the <em>devel load</em> tab provided by <a href=\"@link_devel\">devel module</a> on a %type content page." +msgstr "Лише для досвідчених користувачів: код PHP, що надає значення за замовчуванням. Не повинен містити розмежовувачів <?php ?>. Якщо це поле заповнене, значення, надане цим кодом замістить будь-яке значення, вказане вгорі. Очікуваний формат: <pre>!sample</pre>Для визначення очікуваного формату ви можете скористатись закладкою <em>devel load</em>, наданою <a href=\"@link_devel\">devel module</a> на сторінці контенту %type." + +msgid "Maximum number of values users can enter for this field." +msgstr "Максимальна кількість значень, що користувачі можуть вносити для цього поля" + +msgid "'Unlimited' will provide an 'Add more' button so the users can add as many values as they like." +msgstr "'Необмежено' створить кнопку 'Додати ще', а отже користувачі зможуть додати скільки завгожно власних значенб" + +msgid "The PHP code for 'default value' returned @value, which is invalid." +msgstr "Код PHP для 'базового значення' повернув @value, що є некоректним" + +msgid "%name must be an integer." +msgstr "%name повинно бути цілим" + +msgid "%name must be a positive integer." +msgstr "%name повинно бути позитивним цілим" + +msgid "%name must be a number." +msgstr "%name повинно бути номером" + +msgid "You should make sure that the used field exists in the given content type." +msgstr "Вам потрібно впевнитись, що використовуване поле наявне в даному типі матеріалу" + +msgid "Advanced: Specify the fields value with PHP code" +msgstr "Розширене: Вкажіть значення полей кодом PHP" + +msgid "Advanced usage only: PHP code that returns the value to set. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>Using <a href=\"@link_devel\">devel.module's</a> 'devel load' tab on a content page might help you figure out the expected format." +msgstr "Лише для досвідчених користувачів: код PHP, що надає значення для встановлення. Не повинен містити <?php ?> розмежовувачів. Якщо це поле заповнене, значення, надане цим кодом замістить будь-яке значення, вказане вгорі. Очікуваний формат: <pre>!sample</pre>Використання закладки <a href=\"@link_devel\">devel.module's</a> 'devel load' на сторінці контенту може допомогти вам зрозуміти очікуваний формат." + +msgid "You have to return the default value in the expected format." +msgstr "Потрібно повертати базове значення в передбаченому форматі" + +msgid "Populate @node's field '@field'" +msgstr "Заповнення поля '@field' матеріалу @node" + +msgid "Field has value" +msgstr "Поле має значення" + +msgid "You should make sure that the used field exists in the given content type. The condition returns TRUE, if the selected field has the given value." +msgstr "Вам потрібно переконатись, що дані поля наявні в вказаному типі матеріалу. Повертається TRUE, якщо обрані поля мають вказане значення." + +msgid "Field has changed" +msgstr "Поле змінено" + +msgid "Content containing changes" +msgstr "Матеріал містить зміни" + +msgid "Content not containing changes" +msgstr "Матеріал без змін" + +msgid "@node's field '@field' has value" +msgstr "поле @node '@field' має значення" + +msgid "Select the machine-name of the field to look at." +msgstr "Вибір комп'ютерного імені показаному полю" + +msgid "@node's field '@field' has been changed" +msgstr "Змінено поле '@field' матеріалу @node" + +msgid "Referenced node unfiltered title. WARNING - raw user input." +msgstr "Нефільтрований заголовок пов'язаного матеріалу. Увага - чистий ввід вмд користувача!" + +msgid "Formatted html link to the referenced node." +msgstr "Форматоване HTML посилання до пов'язаного матеріалу" + +msgid "Relative path alias to the referenced node." +msgstr "Відносна адреса до пов'язаного матеріалу" + +msgid "Absolute path alias to the referenced node." +msgstr "Абсолютна адреса до пов'язаного матеріалу" + +msgid "Relative path alias to the referenced user." +msgstr "ВІдносна адреса до пов'язаного користувача" + +msgid "Absolute path alias to the referenced user." +msgstr "Абсолютна адреса до пов'язаного користувача" + +msgid "Field: @widget_label (@field_name) - @field_type" +msgstr "" + +msgid "Field on the referenced node." +msgstr "" + +msgid "Configure how the label is going to be displayed. This option takes no effect when \"Override title\" option is enabled, the specified block title is displayed instead." +msgstr "" + +msgid "Field formatter" +msgstr "" + +msgid "Select a formatter." +msgstr "" + +msgid "\"@s\" field: @widget_label (@field_name) - @field_type" +msgstr "" + +msgid "@label (!name)" +msgstr "@label (!name)" + +msgid "@label (!name) - !column" +msgstr "@label (!name) - !column" + +msgid "@label-truncated - !column" +msgstr "@label-скорочена - !column" + +msgid "Appears in: @types" +msgstr "Використана в: @types" + +msgid "<No value>" +msgstr "<Без значення>" + +msgid "Widget label (@label)" +msgstr "Мітка Візитки (@label)" + +msgid "Custom label" +msgstr "Своя мітка" + +msgid "(first item is 0)" +msgstr "" + +msgid "(start from last values)" +msgstr "" + +msgid "The delta allows you to select which item in a multiple value field to key the relationship off of. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "Допустима похибка дозволяє вам обрати, який елемент в полі з декількома значеннями буде відмикати взаємозв'язок. Оберіть \"1\" для використання першого елемента, \"2\" для другого елемента, і так далі. Якщо ви оберете \"All\", кожен елемент у полі створить новий рядок, що, можливо, створить копії." + +msgid "The delta allows you to select which item in a multiple value field will be used for sorting. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "Допустима похибка дозволяє вам обрати, який елемент в полі з декількома значеннями буде використовуватись для сортування. Оберіть \"1\" для використання першого елемента, \"2\" для другого елемента, і так далі. Якщо ви оберете \"All\", кожен елемент у полі створить новий рядок, що, можливо, створить копії." + +msgid "You need to provide a label." +msgstr "Необхідно вказати мітку" + +msgid "You need to provide a group name." +msgstr "Необхідно вказати ім'я групи" + +msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Назва групи %group_name недійсна. Назва має містити лише малі ненаголошені літери, цифри та підкреслення." + +msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix." +msgstr "Назва групи %group_name занадто довга. Назва обмежена 32 символами, включаючи префікс 'group_'." + +msgid "The group name %group_name already exists." +msgstr "Назва групи %group_name вже існує." + +msgid "Add new group:" +msgstr "Додати нову групу:" + +msgid "Add new group: you need to provide a label." +msgstr "Додати нову групу: потрібно вказати мітку." + +msgid "Add new group: you need to provide a group name." +msgstr "Додати нову групу: потрібно вказати ім'я групи" + +msgid "Standard group" +msgstr "Стандартна група" + +msgid "Create display groups for CCK fields." +msgstr "Створення групи відображення полів CCK" + +msgid "Field group: @group in @type" +msgstr "" + +msgid "All fields from this field group on the referenced node." +msgstr "" + +msgid "Field group label" +msgstr "" + +msgid "Configure how the field group label is going to be displayed. This option takes no effect when \"Override title\" option is enabled, the specified block title is displayed instead." +msgstr "" + +msgid "Fieldset - Collapsible" +msgstr "" + +msgid "Fieldset - Collapsed" +msgstr "" + +msgid "Field group format" +msgstr "" + +msgid "This option allows you to configure the field group format." +msgstr "" + +msgid "\"@s\" field group: @group in @type" +msgstr "" + +msgid "Note that if the field has multiple values, only the first content node will be loaded." +msgstr "Відмітьте, що якщо поле містить численні значення, лише перший вузол контенту буде завантажено." + +msgid "There are no nodereference fields defined." +msgstr "Не визначено жодного поля довідки вузлів." + +msgid "<p>Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note:</p>" +msgstr "" + +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "" + +msgid "<p>The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +msgid "%name: invalid input." +msgstr "%name: неправильне введення" + +msgid "%name: found no valid post with that title." +msgstr "%name: не знайдено дійсного повідомлення з таким заголовком." + +msgid "Only numbers and decimals are allowed in %field." +msgstr "Тільки числа і десяткові значення дозволені в полі %field." + +msgid "Only numbers are allowed in %field." +msgstr "Тільки числа дозволені в полі %field." + +msgid "Only numbers and the decimal character (%decimal) are allowed in %field." +msgstr "Лише цифри та знак дробу (%decimal) дозволені в %field." + +msgid "Note that if the field has multiple values, only the first user will be loaded." +msgstr "Відмітьте, що якщо у поля є численні значення, завантажиться лише перший користувач." + +msgid "There are no userreference fields defined." +msgstr "Немає зазначених полей пов'язаного користувача" + +msgid "Advanced - Users that can be referenced (View)" +msgstr "Розширено - Користувачі, що можуть бути пов'язані (Вигляд)" + +msgid "View used to select the users" +msgstr "Вигляд використано для вибору користувачів" + +msgid "<p>Choose the \"Views module\" view that selects the users that can be referenced.<br />Note:</p>" +msgstr "" + +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.</li></ul>" +msgstr "" + +msgid "<p>The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +msgid "%name: invalid user." +msgstr "%name: некоректний користувач." + +msgid "New field" +msgstr "Нове поле" + +msgid "Existing field" +msgstr "Існуюче поле" + +msgid "New group" +msgstr "Нова група" + +msgid "Add fields and groups to the content type, and arrange them on content display and input forms." +msgstr "Додати поля та групи до типу контенту, і впорядкувати їх на єкранах контенту та формах введення." + +msgid "You can add a field to a group by dragging it below and to the right of the group." +msgstr "Ви можете додати поле до групи, перетянувши його вниз і вправо від групи." + +msgid "Note: Installing the <a href=\"!adv_help\">Advanced help</a> module will let you access more and better help." +msgstr "Зверніть увагу: Встановлення модуля <a href=\"!adv_help\">Advanced help</a> дозволить вам звертатись за більш обсяжною та точнішою допомогою." + +msgid "Use the 'Exclude' checkbox to exclude an item from the !content value passed to the node template." +msgstr "Користуйтесь відміткою 'виключити' для виключення елемента з значення !content, переданого до шаблону вузла." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/uk.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/uk.po new file mode 100644 index 0000000000000000000000000000000000000000..499908372c6dd6fe8eba33456ff896e8ea78b32a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/uk.po @@ -0,0 +1,1754 @@ +# Ukrainian translation of Content Construction Kit (CCK) (all releases) +# Copyright (c) 2009 by the Ukrainian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Content Construction Kit (CCK) (all releases)\n" +"POT-Creation-Date: 2009-10-08 19:18+0000\n" +"PO-Revision-Date: 2009-10-08 22:19+0200\n" +"Language-Team: Ukrainian <podarok@ua.fm>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=((((n%10)==1)&&((n%100)!=11))?(0):(((((n%10)>=2)&&((n%10)<=4))&&(((n%100)<10)||((n%100)>=20)))?(1):2));\n" +"Last-Translator: podarok <podarok@ua.fm>\n" +"X-Poedit-Language: Ukrainian\n" +"X-Poedit-Country: UKRAINE\n" +"X-Poedit-SourceCharset: utf-8\n" + +msgid "CCK" +msgstr "CCK" + +msgid "delete" +msgstr "видалити" + +msgid "Prefix" +msgstr "Префікс" + +msgid "Suffix" +msgstr "Суфікс" + +msgid "Submit" +msgstr "Надіслати" + +msgid "Operations" +msgstr "Дії" + +msgid "Content" +msgstr "Вміст" + +msgid "content" +msgstr "вміст" + +msgid "Groups" +msgstr "Групи" + +msgid "Group" +msgstr "Група" + +msgid "Type" +msgstr "Тип" + +msgid "Cancel" +msgstr "Скасувати" + +msgid "Remove" +msgstr "Вилучити" + +msgid "Description" +msgstr "Опис" + +msgid "Language" +msgstr "Мова" + +msgid "Block title" +msgstr "Назва блоку" + +msgid "Taxonomy" +msgstr "Таксономія" + +msgid "Yes" +msgstr "Так" + +msgid "No" +msgstr "Ні" + +msgid "!date — !username" +msgstr "!date — !username" + +msgid "Content types" +msgstr "Типи матеріалів" + +msgid "Edit" +msgstr "Редагувати" + +msgid "Search" +msgstr "Пошук" + +msgid "None" +msgstr "Жодного" + +msgid "Display settings" +msgstr "Параметри відображення" + +msgid "This action cannot be undone." +msgstr "Цю дію не можна буде скасувати." + +msgid "Number" +msgstr "Число" + +msgid "- None -" +msgstr "- Немає -" + +msgid "Weight" +msgstr "Вага" + +msgid "Help text" +msgstr "Довідковий текст" + +msgid "Types" +msgstr "Типи" + +msgid "Required" +msgstr "Необхідний" + +msgid "none" +msgstr "нічого" + +msgid "Name" +msgstr "Назва" + +msgid "edit" +msgstr "редагувати" + +msgid "Import" +msgstr "Імпорт" + +msgid "Book" +msgstr "Книга" + +msgid "Export" +msgstr "Експорт" + +msgid "Field" +msgstr "Поле" + +msgid "Label" +msgstr "Заголовок" + +msgid "Save" +msgstr "Зберегти" + +msgid "Default" +msgstr "Типовий" + +msgid "Update" +msgstr "Оновити" + +msgid "Add" +msgstr "Додати" + +msgid "remove" +msgstr "видалити" + +msgid "View" +msgstr "Перегляд" + +msgid "Format" +msgstr "Формат" + +msgid "hidden" +msgstr "сховане" + +msgid "Teaser" +msgstr "Анонс" + +msgid "Text" +msgstr "Текст" + +msgid "<none>" +msgstr "<немає>" + +msgid "Content type" +msgstr "Тип вмісту" + +msgid "Continue" +msgstr "Продовжити" + +msgid "Configure" +msgstr "Управління" + +msgid "Node" +msgstr "Матеріал" + +msgid "Include" +msgstr "Включення" + +msgid "Exclude" +msgstr "Виключення" + +msgid "All" +msgstr "Все" + +msgid "Active" +msgstr "Діючий" + +msgid "View arguments" +msgstr "Аргументи вигляду" + +msgid "RSS" +msgstr "RSS" + +msgid "Inline" +msgstr "Вбудоване" + +msgid "Delta" +msgstr "Різниця" + +msgid "Custom" +msgstr "Власний" + +msgid "Poll choices" +msgstr "Варіанти голосів" + +msgid "Content field" +msgstr "Поле матеріалу" + +msgid "Field name" +msgstr "Ім'я поля" + +msgid "Field type" +msgstr "Тип поля" + +msgid "Global settings" +msgstr "Глобальні настройки" + +msgid "Multiple values" +msgstr "" + +msgid "Fields" +msgstr "Поля" + +msgid "Widget type" +msgstr "Тип Візитки" + +msgid "Widget settings" +msgstr "" + +msgid "Contains" +msgstr "Містить" + +msgid "N/A" +msgstr "н/п" + +msgid "configure" +msgstr "налаштувати" + +msgid "Advanced" +msgstr "Додатково" + +msgid "This field is required." +msgstr "Це поле - обов'язкове." + +msgid "Maximum" +msgstr "Найбільше" + +msgid "Scale" +msgstr "Маштаб" + +msgid "Plain text" +msgstr "Чистий текст" + +msgid "Widget" +msgstr "Віджет" + +msgid "Unlimited" +msgstr "Необмежено" + +msgid "Code" +msgstr "Код" + +msgid "General" +msgstr "Загальне" + +msgid "group" +msgstr "група" + +msgid "Basic" +msgstr "Базовий" + +msgid "Filtered text (user selects input format)" +msgstr "Фільтрований текст (користувач обирає вхідний формат)" + +msgid "Text processing" +msgstr "Обробка тексту" + +msgid "Maximum length" +msgstr "Максимальна довжина" + +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "Максимальне значення поля в знаках. Залишіть пустим для необмеженого розміру." + +msgid "%label is longer than %max characters." +msgstr "%label містить більше ніж %max дозволених символів." + +msgid "Rows" +msgstr "Рядки" + +msgid "\"Rows\" must be a positive integer." +msgstr "\"Рядки\" повинні бути додатнім цілим числом." + +msgid "Existing Views" +msgstr "Доступні види" + +msgid "Default Views" +msgstr "Базові види" + +msgid "Empty text" +msgstr "Пустий текст" + +msgid "Order" +msgstr "Замовлення" + +msgid "Integer" +msgstr "Ціле" + +msgid "Edit group" +msgstr "Змінити групу" + +msgid "Add group" +msgstr "Додати групу" + +msgid "Full" +msgstr "Повністю" + +msgid "Size of textfield" +msgstr "Розмір текстового поля" + +msgid "File attachments" +msgstr "Приєднані файли" + +msgid "Show" +msgstr "Показати" + +msgid "Token" +msgstr "Токен" + +msgid "Allowed values list" +msgstr "Список допустимих значень" + +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database and it must match the field storage type, %type. The label is optional and the key will be used as the label if no label is specified." +msgstr "" + +msgid "Select List" +msgstr "Список" + +msgid "Select list" +msgstr "Список" + +msgid "Text field" +msgstr "Текстове поле" + +msgid "body" +msgstr "тіло" + +msgid "PHP code" +msgstr "код PHP" + +msgid "Display fields" +msgstr "Відображення полів" + +msgid "Blocked" +msgstr "Заблоковано" + +msgid "Poll settings" +msgstr "Параметри голосування" + +msgid "Style" +msgstr "Стиль" + +msgid "Your settings have been saved." +msgstr "Ваші параметри збережено" + +msgid "Reversed" +msgstr "" + +msgid "%type settings" +msgstr "Параметри для %type" + +msgid "Menu settings" +msgstr "Налаштування меню" + +msgid "edit " +msgstr "редагування " + +msgid "Illegal value for %name." +msgstr "Недозволене значення %name." + +msgid "<Hidden>" +msgstr "<Приховано>" + +msgid "Comment settings" +msgstr "Налаштування коментарів" + +msgid "Related content" +msgstr "Схожий матеріал" + +msgid "Processing" +msgstr "Обробка" + +msgid "Default value" +msgstr "Базове значення" + +msgid "No content types available." +msgstr "Немає доступних типів матеріалів." + +msgid "Simple" +msgstr "Просте" + +msgid "Above" +msgstr "Над" + +msgid "Number of values" +msgstr "Кількість значень" + +msgid "Warning! Changing this setting after data has been created could result in the loss of data!" +msgstr "Попередження! Зміна цих значень після створення даних можуть призвести до втрат даних!" + +msgid "The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default \"Title\" and \"Body\" may be added. CCK features are accessible through tabs on the <a href=\"@content-types\">content types administration page</a>. (See the <a href=\"@node-help\">node module help page</a> for more information about content types.)" +msgstr "Модуль контенту, обов'язковий компонент Набору побудови контенту (CCK), дозволяє адміністраторам пов'язувати користувацькі поля з типами контенту. В Друпал, типи контенту використовуються для визначення характеристик повідомлення, включаючи заголовок і опис полей, вказаних на сторінках редагування та додавання. Використовуючи модуль контенту (та інші допоміжні модулі в CCK), можна додавати інші користувацькі поля крім полей \"Title\" and \"Body\" за замовчуванням. Можливості CCK доступні через закладки на <a href=\"@content-types\">content types administration page</a>. (Зверніться до <a href=\"@node-help\">node module help page</a> за додатковою інформацією про типи контенту.)" + +msgid "When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a \"person\" may have multiple e-mail addresses) or a single value (i.e., an \"employee\" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules." +msgstr "При доданні користувацького поля до типу контенту ви визначаєте його тип (чи воно буде містити текст, числа чи посилання на інші об'єкти) і те, як воно буде показане (або у вигляді текстового поля, прямокутника з варіантами, відмітками багатозначного чи однозначного вибору, чи автозаповнювальним полем). Поле може мати декілька значень (наприклад, \"person\" може містити декілька адрес електронної пошти) або єдине значення (наприклад, \"employee\" містить один ідентифікаційний номер працівника). Під час додавання та редагування полей, CCK автоматично корегує структуру бази даних за необхідністю. CCK також надає й інші можливості, включаючи інтелектуальне резервування ваших користувацьких даних, модуль імпорту/експорту для визначень типу контенту та інтеграцію з іншими приєднаними модулями." + +msgid "Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href=\"@modules\">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:" +msgstr "Користувацькі типи полів надаються набором додаткових модулів, включених з CCK (кожен модуль підтримує різний тип). <a href=\"@modules\">modules page</a> дозволяє вам вмикати та вимикати складові CCK. Стандартне встановлення CCK включає в себе:" + +msgid "<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available." +msgstr "<em>number</em>, що додає числові типи полей, у цілій, дробній чи з плаваючою комою формі чисел. Ви можете визначити набір дозволених даних для введення, або вказати допустимий окіл значень. В асортименті є набір звичайних форматів для показу числових даних." + +msgid "<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values." +msgstr "<em>text</em>, що додає текстові типи полей. Текстове поле може містити лише простий текст, або, за бажанням, може використовувати фільтри формату вводу Drupal'у для безпечної роботи з введенням збагаченого тексту. Поля введення текту можуть бути у вигляді одної строки, декількох строк (текстового поля), або для більшого контролю, прямокутника з варіантами, відмітками багатозначного чи однозначного вибору. За бажанням, CCK може звірювати введене з набором дозволених значень" + +msgid "<em>nodereference</em>, which creates custom references between Drupal nodes. By adding a <em>nodereference</em> field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple \"employee\" nodes may contain a <em>nodereference</em> field linking to an \"employer\" node)." +msgstr "<em>nodereference</em>, що створює користувацькі посилання між вузлами Drupal. Наприклад, додаючи поле <em>nodereference</em> і два різних типа контенту, ви можете з легкістю створювати складні спадкові стосунки між даними (декілька вузлів \"employee\" можуть містити поле <em>nodereference</em>, що пов'язує їх з вузлом \"employer\")." + +msgid "<em>userreference</em>, which creates custom references to your sites' user accounts. By adding a <em>userreference</em> field, you can create complex relationships between your site's users and posts. To track user involvement in a post beyond Drupal's standard <em>Authored by</em> field, for instance, add a <em>userreference</em> field named \"Edited by\" to a content type to store a link to an editor's user account page." +msgstr "<em>userreference</em>, що створює користувацькі посилання на рахунки користувачів вашого сайту. Додаючи поле <em>userreference</em>, ви можете створювати складні взаємозв'зки між користувачами та повідомленнями вашого сайту. Наприклад, для відслідковування участі користувачів у повідомленні понад стандартного поля Drupal <em>Authored by</em>, додайте поле <em>userreference</em> з назвою \"Edited by\" до типу контенту, щоб зберегти посилання на сторінку рахунку редактора повідомлення." + +msgid "<em>fieldgroup</em>, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module." +msgstr "<em>fieldgroup</em>, що створює розбірні набори полів для фіксування групи пов'язаних полів. Набір полів може бути відкритим чи закритим за замовчуванням. Порядок ваших наборів полів, а також порядок полів в наборі, управляється через перетягування у інтерфейсі, наданому модулем контенту." + +msgid "For more information, see the online handbook entry for <a href=\"@handbook-cck\">CCK</a> or the <a href=\"@project-cck\">CCK project page</a>." +msgstr "Для додаткової інформації читайте розділ довідника <a href=\"@handbook-cck\">CCK</a> на сторінці <a href=\"@project-cck\">CCK проекту</a>." + +msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode." +msgstr "Налаштувати те, як поля цього типу контенту та мітки полів повинні бути показані в режимах короткого та повного перегляду." + +msgid "Configure how this content type's fields should be displayed when it's rendered in the following contexts." +msgstr "Налаштувати те, як поля цього типу контенту повинні бути показані під час обробки в наступних контекстах." + +msgid "Control the order of fields in the input form." +msgstr "Налаштування послідовності полів у формі вводу." + +msgid "!title: !required" +msgstr "!title: !required" + +msgid "Add another item" +msgstr "Додати інший елемент" + +msgid "Full node" +msgstr "Повний матеріал" + +msgid "RSS Item" +msgstr "" + +msgid "Search Index" +msgstr "База пошуку" + +msgid "Search Result" +msgstr "Результат пошуку" + +msgid "Updating field type %type with module %module." +msgstr "Оновлення типу поля %type модулем %module." + +msgid "Updating widget type %type with module %module." +msgstr "Оновлення типу Візитки %type модулем %module." + +msgid "Manage fields" +msgstr "Керувати полями" + +msgid "Add field" +msgstr "Додати поле" + +msgid "Remove field" +msgstr "Видалення поля" + +msgid "Allows administrators to define new content types." +msgstr "Дозволяє адміністраторам задавати новий тип матеріалу" + +msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "Лише для досвідчених користувачів: код PHP, що видає відповідний набір дозволених значень. Не повинен включати розмежовувачів <?php ?>. Якщо це поле заповнене, набір, виданий цім кодом, замістить вищевказаний перелік дозволених значень." + +msgid "Trimmed" +msgstr "Скорочене" + +msgid "Text area" +msgstr "Текстове поле" + +msgid "Used in" +msgstr "Використано в" + +msgid "No fields have been defined for any content type yet." +msgstr "Жодних полів ще не задано для жодного типу матеріалів" + +msgid "There are no fields configured for this content type. You can !link." +msgstr "Немає полів налаштованих на використання в цьому типі контенту. Ви можете !link." + +msgid "Add a new field" +msgstr "Додати нове поле" + +msgid "To change the order of a field, grab a drag-and-drop handle under the Label column and drag the field to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the Save button at the bottom of the page." +msgstr "" + +msgid "no styling" +msgstr "без стилю" + +msgid "simple" +msgstr "просто" + +msgid "fieldset" +msgstr "група полів" + +msgid "fieldset - collapsible" +msgstr "група полів - здатна звертатись" + +msgid "fieldset - collapsed" +msgstr "група полів - звернута" + +msgid "Add existing field" +msgstr "" + +msgid "Create new field" +msgstr "Створити нове поле" + +msgid "The machine-readable name of the field. This name cannot be changed later! The name will be prefixed with 'field_' and can include lowercase unaccented letters, numbers, and underscores. You'll be able to choose a human-readable label for the field on next page." +msgstr "Системна назва поля. Цю назву <strong>неможна</strong> буде змінити згодом! До назви буде додано префікс 'field_'. Назва може містити прописні ненаголошені букви латинського алфавіту, цифри та символи нижнього підкреслення. Ви будете мати можливість ввести назву поля, яка буде відображатися для користувачів, на наступній сторінці." + +msgid "No field modules are enabled. You need to <a href=\"!modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "" + +msgid "Choose the type of value to store and an input method from the list below." +msgstr "" + +msgid "Added field %label." +msgstr "Додано поле %label" + +msgid "There was a problem adding field %label." +msgstr "Виникла проблема додавання поля %label." + +msgid "The field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Назва поля %field_name неправильна. Назва може містити прописні ненаголошені букви латинського алфавіту, цифри та символи нижнього підкреслення." + +msgid "The field name %field_name already exists." +msgstr "Назва поля %field_name вже існує." + +msgid "The name 'field_instance' is a reserved name." +msgstr "Назва 'field_instance' зарезервована." + +msgid "Created field %label." +msgstr "Створити поле %label." + +msgid "There was a problem creating field %label." +msgstr "Виникла проблема створення поля %label." + +msgid "Are you sure you want to remove the field %field?" +msgstr "Ви впевнені, що хочете видалити поле %field?" + +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Якщо в даному полі знаходиться якийсь матеріал - він буде втрачений. Це незворотня операція" + +msgid "Removed field %field from %type." +msgstr "Видалено поле %field із %type." + +msgid "There was a problem deleting %field from %type." +msgstr "Виникла проблема видалення %field із %type." + +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Ці параметри застосовуються тільки до поля %field так як знаходиться в типі матеріалу %type" + +msgid "Instructions to present to the user below this field on the editing form." +msgstr "" + +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format :<pre>!sample</pre>Using !link_devel's 'devel load' tab on a %type content page might help you figure out the expected format." +msgstr "" + +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Ці параметри застосовуються до поля %field в кожному типі матеріалів, в якому воно використовуються." + +msgid "Select a specific number of values for this field, or 'Unlimited' to provide an 'Add more' button so the users can add as many values as they like." +msgstr "" + +msgid "Save field settings" +msgstr "Збереження параметрів поля" + +msgid "The default value PHP code returned an incorrect value.<br/>Expected format: <pre>!sample</pre> Returned value: @value" +msgstr "Код PHP значення за замовчуванням видав неправильне значення.<br/>Очікуваний формат: <pre>!sample</pre> Видане значення: @value" + +msgid "The default value PHP code created @value which is invalid." +msgstr "" + +msgid "The default value is invalid." +msgstr "Базове значення некоректне" + +msgid "Saved field %label." +msgstr "Збережено поле %label" + +msgid "The update has encountered an error." +msgstr "Оновлення викликало помилку" + +msgid "The database has been altered and data has been migrated or deleted." +msgstr "База даних змінена і дані переміщено або видалено." + +msgid "An error occurred and database alteration did not complete." +msgstr "Виникла помилка і зміни в базі даних незавершені." + +msgid "Processing %title" +msgstr "Обробка %title" + +msgid "1 item successfully processed:" +msgid_plural "@count items successfully processed:" +msgstr[0] "вдало оброблено @count елемент:" +msgstr[1] "вдало оброблено @count елементи:" +msgstr[2] "вдало оброблено @count елементів:" + +msgid "Content fields table %old_name has been renamed to %new_name and field instances have been updated." +msgstr "Таблиця %old_name полей матеріалу була перейменована в %new_name і елементи полей були оновлені" + +msgid "The content fields table %name has been deleted." +msgstr "Таблиця %name полей матеріалу була видалена" + +msgid "Add another !field value" +msgstr "Додати інше значення !field" + +msgid "If the amount of boxes above isn't enough, click here to add more items." +msgstr "" + +msgid "Referenced node ID" +msgstr "ID пов'язаного матеріалу" + +msgid "Referenced node title" +msgstr "Заголовок пов'язаного матеріалу" + +msgid "Formatted HTML link to the node" +msgstr "" + +msgid "Raw number value" +msgstr "Чисте значення номера" + +msgid "Formatted number value" +msgstr "Форматоване значення номера" + +msgid "Raw, unfiltered text" +msgstr "Чистий, нефільтрований текст" + +msgid "Formatted and filtered text" +msgstr "Форматований і фільтрований текст" + +msgid "Referenced user ID" +msgstr "ID пов'язаного користувача" + +msgid "Referenced user name" +msgstr "Ім'я пов'язаного користувача" + +msgid "Formatted HTML link to referenced user" +msgstr "Форматоване HTML посилання до пов'язаного користувача" + +msgid "Appears in : @types" +msgstr "З'являється в : @types" + +msgid "Group multiple values" +msgstr "Багато значень групи" + +msgid " values," +msgstr " значення," + +msgid "Starting from" +msgstr "Починати з" + +msgid "Start from last values" +msgstr "Починати з останнього значення" + +msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields." +msgstr "Ця форма обробить тип контенту та одне або декілька полів цього типу, та експортує налаштування. Експортування, створене цим процесом, можна копіювати та вставляти як імпортування у поточну або будь-яку іншу базу даних. Імпортування додасть поля в існуючий тип контенту або створить новий тип контенту, що включає обрані поля." + +msgid "Select the content type to export." +msgstr "Вибір типу матеріалу для вивантаження" + +msgid "Select the group definitions to export from %type." +msgstr "" + +msgid "Select the field definitions to export from %type." +msgstr "" + +msgid "Export data" +msgstr "Вивантаження даних" + +msgid "Copy the export text and paste it into another content type using the import function." +msgstr "Скопіюйте текст експорту та вставте його в інший тип контенту, використовуючи функцію імпорту." + +msgid "This form will import field definitions exported from another content type or another database.<br/>Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type." +msgstr "Ця форма імпортує визначення полів, експортовані з іншого типу контенту або іншої бази даних. <br/>Зверніть увагу, що поля не можна копіювати всередині одного типу контенту, так що імпортовані поля будуть додані лише у тому випадку, якщо вони ще не існують в обраному типу." + +msgid "<Create>" +msgstr "<Створення>" + +msgid "Select the content type to import these fields into.<br/>Select <Create> to create a new content type to contain the fields." +msgstr "Оберіть тип контенту для імпортування вказаних полів. <br/>Оберіть <Create> для створення нового типу контенту для вміщення полів." + +msgid "Import data" +msgstr "Втягування даних" + +msgid "Paste the text created by a content export into this field." +msgstr "Вставте текст, створений експортуванням контенту, у це поле." + +msgid "The import data is not valid import text." +msgstr "Дані для втягування не є коректними" + +msgid "The following modules must be enabled for this import to work: %modules." +msgstr "Наступні модулі слід включити для роботи цього імпортування: %modules." + +msgid "<create>" +msgstr "<Створення>" + +msgid "The content type %type already exists in this database." +msgstr "Тип матеріалу %type вже міститься в базі даних." + +msgid "Exiting. No import performed." +msgstr "Вихід. Не виконано втягування;" + +msgid "An error has occurred adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "Трапилась помилка при доданні типу контенту %type.<br/>Будь ласка, прогляньте вказані помилки для докладних деталей." + +msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type." +msgstr "Втягнуте поле %field_label (%field_name) не було додано до %type через те, що поле вже існує в %type." + +msgid "The field %field_label (%field_name) was added to the content type %type." +msgstr "Поле %field_label (%field_name) додано до типу матеріалів %type." + +msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'." +msgstr "Трапилась помилка при експортуванні даних 'показу налаштувань' для поля %field_name.<br/> Помилка бази даних наступна: '%db_err'." + +msgid "Content Copy" +msgstr "Копіювання матеріалів" + +msgid "Enables ability to import/export field definitions." +msgstr "Включає здатність імпортувати/експортувати визначення полей." + +msgid "field_name" +msgstr "ім'я поля" + +msgid "view " +msgstr "вигляд " + +msgid "Please <a href=\"!url\">configure your field permissions</a> immediately. All fields are inaccessible by default." +msgstr "Будь ласка негайно <a href=\"!url\">configure your field permissions</a>. Всі поля за замовчуванням недоступні." + +msgid "Content Permissions" +msgstr "Доступи до матеріалів" + +msgid "Set field-level permissions for CCK fields." +msgstr "Встановіть дозволи рівнів полей для полей CCK." + +msgid "These settings apply to the group in the node editing form." +msgstr "Ці параметри використовувати до групи в формі редагування матеріалу" + +msgid "always open" +msgstr "завжди відкрите" + +msgid "collapsible" +msgstr "можливість звертання" + +msgid "collapsed" +msgstr "звернуто" + +msgid "Instructions to present to the user on the editing form." +msgstr "Інструкції, що відображаються користувачу на формі редагування" + +msgid "These settings apply to the group on node display." +msgstr "Ці налаштування стосуються групи на екрані вузлів." + +msgid "A description of the group." +msgstr "Опис групи" + +msgid "The group name %name already exists." +msgstr "Назва групи %name вже існує." + +msgid "The group name %name is invalid." +msgstr "Назва групи %name неправильна." + +msgid "Are you sure you want to remove the group %label?" +msgstr "Ви впевнені, що хочете видалити групу %label?" + +msgid "The group %group_name has been removed." +msgstr "Групу %label видалено" + +msgid "Display in group" +msgstr "Відображати в групі" + +msgid "Select a group, in which the field will be displayed on the editing form." +msgstr "" + +msgid "Fieldgroup" +msgstr "Група полів" + +msgid "Create field groups for CCK fields." +msgstr "Створити групи для для CCK полів" + +msgid "Node reference" +msgstr "Посилання на матеріал" + +msgid "Store the ID of a related node as an integer value." +msgstr "Зберегти ІН пов'язаного вузлу цілим числом." + +msgid "Content types that can be referenced" +msgstr "Типи контенту, що мона ввести в довідку" + +msgid "Advanced - Nodes that can be referenced (View)" +msgstr "Розширене - вузли, що можна внести в довідку (Переглянути)" + +msgid "Choose the \"Views module\" view that selects the nodes that can be referenced.<br>Note :<ul><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "" + +msgid "Provide a comma separated list of arguments to pass to the view." +msgstr "Надайте перелік аргументів, розділений комами, для передачи на перегляд." + +msgid "%name : This post can't be referenced." +msgstr "" + +msgid "Title (link)" +msgstr "Назва(посилання)" + +msgid "Title (no link)" +msgstr "Назва(без посилання)" + +msgid "Autocomplete text field" +msgstr "Текстове поле автозаповнення" + +msgid "%name: Title mismatch. Please check your selection." +msgstr "" + +msgid "Nodereference autocomplete" +msgstr "Автодоповнення посилання на матеріал" + +msgid "Node Reference" +msgstr "Посилання на матеріал" + +msgid "Defines a field type for referencing one node from another." +msgstr "визначає тип поля для відрізняння одного вузла від іншого." + +msgid "Store a number in the database as an integer." +msgstr "Зберегти як ціле число в базі даних." + +msgid "Decimal" +msgstr "Десяткове" + +msgid "Store a number in the database in a fixed decimal format." +msgstr "Зберегти як фіксоване дробне число в базі даних." + +msgid "Float" +msgstr "Плаваюче" + +msgid "Store a number in the database in a floating point format." +msgstr "Зберегти як число з плаваючою комою в базі даних." + +msgid "Minimum" +msgstr "Найменше" + +msgid "Precision" +msgstr "Точність" + +msgid "The total number of digits to store in the database, including those to the right of the decimal." +msgstr "Загальне число цифр для збереження в базі даних, включаючи ті, що справа від знаку дробу." + +msgid "The number of digits to the right of the decimal." +msgstr "Кількість цифр справа від знаку дробу." + +msgid "Decimal marker" +msgstr "Десятковий розділювач" + +msgid "The character users will input to mark the decimal point in forms." +msgstr "Знак, який користувачі введуть для відмічення знаку дробу у формах." + +msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Визначіть строку-префікс для значення, наприклад $ або €. Залишіть пустим для нічого. Розділіть значення однини та множини знаком | (фунт|фунти)." + +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)." +msgstr "Визначіть строку-суфікс для значення, наприклад m², m/s², kb/s. Залишіть пустим для нічого. Розділіть значення однини та множини знаком | (фунт|фунти)." + +msgid "Allowed values" +msgstr "Дозволені значення" + +msgid "\"Minimum\" must be a number." +msgstr "\"Найменше\" повинно бути числом." + +msgid "\"Maximum\" must be a number." +msgstr "\"Найбільше\" повинно бути числом" + +msgid "The value of %name may be no smaller than %min." +msgstr "%name: значення повинно бути не меншим чим %min." + +msgid "The value of %name may be no larger than %max." +msgstr "%name: значення повинно бути не більшим чим %max." + +msgid "unformatted" +msgstr "неформатоване" + +msgid "Only numbers and decimals are allowed in %field. %start was changed to %value." +msgstr "" + +msgid "Only numbers are allowed in %field. %start was changed to %value." +msgstr "" + +msgid "Only numbers and the decimal character (%decimal) are allowed in %field. %start was changed to %value." +msgstr "" + +msgid "Defines numeric field types." +msgstr "Зазначення числових типів полей" + +msgid "Create a list of options as a list in <strong>Allowed values</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "" + +msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "Для віджету 'один прямокутник з варіантами ввімнути/вимкнути' визначіть спочатку значення 'вимкнути', а потім значення 'ввімкнути' у розділі <strong>Allowed values</strong>. Зверніт увагу, прямокутник буде помічено міткою значення 'ввімкнути'." + +msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "Віджет 'прямокутники з варіантами' буде показувати багатоваріантний вибір, якщо ця опція обрана для цього поля, інакше буде вказано одноваріантний вибір." + +msgid "Check boxes/radio buttons" +msgstr "Відмітьте квадратики/кнопки" + +msgid "Single on/off checkbox" +msgstr "Одиночна опція так/ні" + +msgid "Option Widgets" +msgstr "Спецдодатки" + +msgid "Defines selection, check box and radio button widgets for text and numeric fields." +msgstr "Визначає віджети вибору та прямокутників з варіантами для текстових та числових полей." + +msgid "Store text in the database." +msgstr "Збереження тексту в базі даних" + +msgid "Text area (multiple rows)" +msgstr "Текстове поле (багаторядкове)" + +msgid "Defines simple text field types." +msgstr "Надання простих текстових типів полів" + +msgid "User reference" +msgstr "Посилання на користувача" + +msgid "Store the ID of a related user as an integer value." +msgstr "Збереження ID пов'язаного користувача як ціле значення" + +msgid "User roles that can be referenced" +msgstr "Ролі користувачів можуть бути пов'язані" + +msgid "User status that can be referenced" +msgstr "Статус користувача може бути пов'язаний" + +msgid "%name: Invalid user." +msgstr "" + +msgid "Reverse link" +msgstr "Зворотнє посилання" + +msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record." +msgstr "При обранні, буде показано обернене посилання на вузол довідки на запису внесеного користувача." + +msgid "Userreference autocomplete" +msgstr "Автозаповнення довідки користувачів" + +msgid "User Reference" +msgstr "Посилання на користувача" + +msgid "Defines a field type for referencing a user from a node." +msgstr "Визначає тип поля для знаходження користувача з вузла." + +msgid "node reference autocomplete" +msgstr "" + +msgid "Autocomplete Text Field" +msgstr "" + +msgid "%name : Title mismatch. Please check your selection." +msgstr "" + +msgid "<empty>" +msgstr "<пусто>" + +msgid "Text Field" +msgstr "" + +msgid "Node context" +msgstr "Вміст матеріалу" + +msgid "Print" +msgstr "Друк" + +msgid "Locked" +msgstr "Заблоковано" + +msgid "Create field" +msgstr "" + +msgid "No group" +msgstr "" + +msgid "No fields have been added to this group." +msgstr "" + +msgid "!label (!name)" +msgstr "!label (!name)" + +msgid "Updated field groups." +msgstr "" + +msgid "Updated field weights." +msgstr "" + +msgid "Data settings" +msgstr "" + +msgid "There are no groups configured for this content type." +msgstr "" + +msgid "There are no fields configured for this content type." +msgstr "" + +msgid "Updated group weights." +msgstr "" + +msgid "The machine-readable name of the field.<br/>Allowed characters : unaccentuated a-z, numbers and _. All other characters will be discarded.<br/>You'll be able to choose a human-readable label for the field on next page" +msgstr "" + +msgid "The field name %field_name is invalid." +msgstr "" + +msgid "Instructions to present to the user below this field on the editing form.<br />Allowed HTML tags: @tags" +msgstr "Інструкції, що відобразяться користувачу нижче цього поля на формі редагування. <br />Дозволені HTML теги: @tags" + +msgid "Advanced Usage Only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format :<pre>!sample</pre>Using !link_devel 'devel load' tab on a %type content page might help you figure out the expected format." +msgstr "" + +msgid "<none>" +msgstr "<нема>" + +msgid "You're not allowed to input PHP code." +msgstr "Вам недозволено ввожити PHP код" + +msgid "This PHP code was set by an administrator and will override any value specified above." +msgstr "Код PHP був встановлений адміністратором і буде перезаписувати будь-які значенн, вказані вище" + +msgid "The default value PHP code returned an incorrect value<br/>Expected format : <pre>!sample</pre>Returned value : @value" +msgstr "" + +msgid "Saved field %field." +msgstr "" + +msgid "No PostgreSQL mapping found for %type data type." +msgstr "" + +msgid "database" +msgstr "" + +msgid "The content fields table %name has been created." +msgstr "" + +msgid "A content field from the referenced node." +msgstr "Поле матеріалу з пов'язаного матеріалу" + +msgid "Configure how the label is going to be displayed" +msgstr "" + +msgid "Field / Formatter" +msgstr "Поле / Форматувальник" + +msgid "Select a field and formatter." +msgstr "Оберіть поле і форматувальник" + +msgid "\"@s\" field @name" +msgstr "\"@s\" поле @name" + +msgid "Do not group multiple values" +msgstr "" + +msgid "Show first value only" +msgstr "" + +msgid "Show last value only" +msgstr "" + +msgid "Use PHP input for field settings (dangerous - grant with care)" +msgstr "Використання PHP для параметрів поля (небезпечно - використовуйте з обережністю)" + +msgid "A file has been pre-loaded for import." +msgstr "Файл для втягування завантажено" + +msgid "An error has occured adding the content type %type.<br/>Please check the errors displayed for more details." +msgstr "" + +msgid "An error has occured adding the field %field_label (%field_name).<br/>Please check the errors displayed for more details." +msgstr "" + +msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field settings.<br/>Please check the errors displayed for more details." +msgstr "" + +msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field's 'display_settings'.<br/>The db error is: '%db_err'." +msgstr "" + +msgid "These settings apply to the group in the node editing form" +msgstr "" + +msgid "Content fieldgroup" +msgstr "Група полей матеріалу" + +msgid "Content fieldgroup content goes here." +msgstr "" + +msgid "All fields from a fieldgroup on the referenced node." +msgstr "Всі поля з групи полей на вказаному вузлі." + +msgid "Text to display if group has no data. Note that title will not display unless overridden." +msgstr "Текст для показу у випадку, коли у групі нема даних. Відмітьте, що заголовок не буде показано, хіба що не відбудетья відміна." + +msgid "\"@s\" fieldgroup @name" +msgstr "\"@s\" група полей @name" + +msgid "%name: Found no valid post with that title." +msgstr "" + +msgid "Node from reference" +msgstr "" + +msgid "Adds a node from a node reference in a node context; if multiple nodes are referenced, this will get the first referenced node only." +msgstr "" + +msgid "Node reference field" +msgstr "" + +msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds). " +msgstr "" + +msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified.<br />Allowed HTML tags: @tags" +msgstr "Можливі значення цього поля. Введіть по одному значенню на строку, в форматі ключ|мітка. Ключ - значення, що буде збережене в базі даних, і воно має співпадати з типом збереження поля (%type). Мітка необов'язкова, і ключ буде використано замість неї, якщо вона не вказана.<br /> Дозволені мітки HTML: @tags" + +msgid "Advanced Usage Only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above." +msgstr "" + +msgid "This PHP code was set by an administrator and will override the allowed values list above." +msgstr "Цей код PHP був встановлений адміністратором і замістить вищевказаний перелік дозволених значень." + +msgid "Create a list of options as a list in <strong>Allowed values</strong> or as an array in PHP code at the bottom of this page. These values will be the same for the %field in all content types. " +msgstr "" + +msgid "For a 'Single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value." +msgstr "" + +msgid "The 'Checkboxes / radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed." +msgstr "" + +msgid "Set the option to the number of initial characters to filter by. Leave empty for full term; use 1 for an A/B/C style glossary." +msgstr "" + +msgid "user reference autocomplete" +msgstr "" + +msgid "%name : Invalid user." +msgstr "" + +msgid "Reverse Link" +msgstr "" + +msgid "Related Content" +msgstr "" + +msgid "User from reference" +msgstr "" + +msgid "Adds a user from a user reference in a node context; if multiple users are referenced, this will get the first referenced user only." +msgstr "" + +msgid "User reference field" +msgstr "" + +msgid "<div>The allowed values list for %field was updated from </div><pre>%start</pre><div> to </div><pre>%end</pre><div>You can go to the field settings page to give each option a more user-friendly label." +msgstr "" + +msgid "<div>The allowed values list for %field was not changed from </div><pre>%start</pre>" +msgstr "" + +msgid "Show @count value(s)" +msgstr "Відображення @count значень" + +msgid "starting from @count" +msgstr "починаючи з @count" + +msgid "@label (!name) - Allowed values" +msgstr "@label (!name) - Дозволені значення" + +msgid "%name: illegal value." +msgstr "%name: значення некоректне." + +msgid "%name: the value may not be longer than %max characters." +msgstr "%name: значення не може бути довшим чим %max символів" + +msgid "Autocomplete matching" +msgstr "Порівняння автозаповнення" + +msgid "Starts with" +msgstr "Починається з" + +msgid "Load a referenced user" +msgstr "Завантажити згаданого користувача" + +msgid "Content containing the user reference field" +msgstr "Матеріал містить поле пов'язаного користувача" + +msgid "Referenced user" +msgstr "Згаданий користувач" + +msgid "Load a referenced node" +msgstr "Завантаження пов'язаного матеріалу" + +msgid "Content containing the node reference field" +msgstr "Контент, що містить поле довідки вузлу" + +msgid "Referenced content" +msgstr "Пов'язаний матеріал" + +msgid "Populate a field" +msgstr "Заповнення поля" + +msgid "Select the machine-name of the field." +msgstr "Вибір комп'ютерного імені поля" + +msgid "Revision information" +msgstr "Інформація про зміни" + +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of users." +msgstr "Оберіть метод збору підказок щодо автозаповнення. Зверніть увагу, що <em>Contains</em> може призвести до проблем з продуктивністю на сайтах з тисячами вузлів." + +msgid "View used to select the nodes" +msgstr "Перегляд для вибору вузлів" + +msgid "%name: this post can't be referenced." +msgstr "%name: Це повідомлення не можна внести в довідку." + +msgid "Node module form." +msgstr "Форма модуля матеріалу" + +msgid "Locale module form." +msgstr "Форма модуля перекладів" + +msgid "Taxonomy module form." +msgstr "Форма модуля таксономії" + +msgid "Poll title" +msgstr "Назва Голосування" + +msgid "'@column' => value for @column" +msgstr "'@column' => значення для @column" + +msgid "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" +msgstr "" +"return array(\n" +" 0 => array(@columns),\n" +" // You'll usually want to stop here. Provide more values\n" +" // if you want your 'default value' to be multi-valued:\n" +" 1 => array(@columns),\n" +" 2 => ...\n" +");" + +msgid "Create a list of options as a list in <strong>Allowed values list</strong> or as an array in PHP code. These values will be the same for %field in all content types." +msgstr "Створіть перелік опцій в формі <strong>Allowed values list</strong> або як набір в коді PHP. Ці значення будуть однаковими для %field у всіх типах контенту." + +msgid "You need to specify the 'allowed values' for this field." +msgstr "Необхідно задавати 'дозвроені значення' для цього поля" + +msgid "Change basic information" +msgstr "Зміна базової інформації" + +msgid "Fieldset" +msgstr "Набір полей" + +msgid "Translation settings" +msgstr "Параметри Перекладу" + +msgid "Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes." +msgstr "Оберіть метод пошуку підказок автозаповнення. Зверніть увагу, що <em>Contains</em> може призвести до проблем з продуктивністю на сайтах з тисячами вузлів." + +msgid "%name: title mismatch. Please check your selection." +msgstr "%name: неспівпадіння заголовку. Будь ласка, провірте ваш вибір." + +msgid "Path settings" +msgstr "" + +msgid "%name: the value may be no smaller than %min." +msgstr "%name: значення повинно бути не меншим чим %min." + +msgid "%name: the value may be no larger than %max." +msgstr "%name: значення повинно бути не більшим чим %max." + +msgid "%name: found no valid user with that name." +msgstr "%name: не знайдено дійсного користувача з таким ім'ям." + +msgid "Field label" +msgstr "" + +msgid "Form settings" +msgstr "Параметри форми" + +msgid "Type of group." +msgstr "Тип групи" + +msgid "%name: this field cannot hold more that @count values." +msgstr "%name: це поле не може отримати більше чим @count значень." + +msgid "If unchecked, each item in the field will create a new row, which may appear to cause duplicates. This setting is not compatible with click-sorting in table displays." +msgstr "Якщо не обрано, кожен елемент поля буде створювати новий рядок, що може привести до дублів. Ці параметри несумісні з сортуванням таблиць при кліках на відображенні." + +msgid "Some updates are still pending. Please return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Деякі оновлення все ще в черзі. Прохання повернутись до <a href=\"@update-php\">update.php</a> і запустити необхідні оновлення" + +msgid "Some updates are still pending.<br/>Please re-run the update script." +msgstr "Деякі оновлення ще знаходяться в черзі. <br/>Будь ласка, заново запустіть скрипт оновлення." + +msgid "Comment module form." +msgstr "" + +msgid "Translation module form." +msgstr "" + +msgid "Menu module form." +msgstr "Форма модуля меню" + +msgid "Book module form." +msgstr "Форма модуля Книг" + +msgid "Path module form." +msgstr "" + +msgid "Poll module title." +msgstr "Назва модуля голосувань" + +msgid "Poll module choices." +msgstr "Варіанти модуля голосувань" + +msgid "Poll module settings." +msgstr "Параметри модуля голосувань" + +msgid "Upload module form." +msgstr "форма модуля Завантажень" + +msgid "Updates for CCK-related modules are not run until the modules are enabled on the <a href=\"@admin-modules-path\">administer modules page</a>. When you enable them, you'll need to return to <a href=\"@update-php\">update.php</a> and run the remaining updates." +msgstr "Оновлення для модулів, пов'язаних з CCK, не відбуваються до включення модулів на <a href=\"@admin-modules-path\">administer modules page</a>. Коли ви включите їх, вам слід повернутись до <a href=\"@update-php\">update.php</a> і провести оновлення, що залишились." + +msgid "!module.module has updates but cannot be updated because content.module is not enabled.<br />If and when content.module is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "!module.module має оновлення, але не може їх розпочати з-за відключення content.module. <br />Якщо і коли content.module буде включено, вам потрібно буде повторно запустити скрипт оновлення. Ви будете й надалі бачити це повідомлення, аж поки модуль не буде включено і оновлення пройдені." + +msgid "!module.module has updates and is available in the modules folder but is not enabled.<br />If and when it is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run." +msgstr "!module.module має оновлення і доступний в папці модулів, але він не включений. <br />Якщо і коли його буде включено, вам потрібно буде повторно запустити скрипт оновлення. Ви будете й надалі бачити це повідомлення, аж поки модуль не буде включено і оновлення пройдені." + +msgid "CCK - No Views integration" +msgstr "CCK - без інтеграції з Виглядама" + +msgid "CCK integration with Views module requires Views 6.x-2.0-rc2 or greater." +msgstr "CCK - інтеграція з Виглядама потребує Views 6.x-2.0-rc2 або новіше" + +msgid "manage fields" +msgstr "керування полями" + +msgid "» Add a new content type" +msgstr "» Додавання нового типу матеріалу" + +msgid "@field_name (Locked)" +msgstr "@field_name (Заблоковано)" + +msgid "This content type has inactive fields. Inactive fields are not included in lists of available fields until their modules are enabled." +msgstr "Цей тип матеріалу має неактивні поля. Неактивні поля не включені в список доступних до моменту вмикання їхніх модулів" + +msgid "!field (!field_name) is an inactive !field_type field that uses a !widget_type widget." +msgstr "!field (!field_name) неактивне поле !field_type що використовує Візитку !widget_type." + +msgid "- Select a field type -" +msgstr "- Вибір типу поля -" + +msgid "- Select a widget -" +msgstr "- Вибір widget -" + +msgid "Field name (a-z, 0-9, _)" +msgstr "Ім'я поля (a-z, 0-9, _)" + +msgid "Type of data to store." +msgstr "Тип даних для збереження" + +msgid "Form element to edit the data." +msgstr "Елемент форми для зміни даних" + +msgid "- Select an existing field -" +msgstr "- Вибір наявного поля -" + +msgid "Field to share" +msgstr "Поле для відображення" + +msgid "Group name (a-z, 0-9, _)" +msgstr "Ім'я групи (a-z, 0-9, _)" + +msgid "Add new field: you need to provide a label." +msgstr "Додавання нового поля: Вам потрібно вказати мітку" + +msgid "Add new field: you need to provide a field name." +msgstr "Додавання нового поля: Вам потрібно вказати ім'я поля" + +msgid "Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Додавання нового поля: ім'я поля %field_name - некоректне. Ім'я повинно включати лише латинські символи, цифри і підкреслення" + +msgid "Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix." +msgstr "Додавання нового поля: ім'я поля %field_name надто довге. Ім'я обмежено 32 символами, включаючи префікс 'field_'" + +msgid "Add new field: the name 'field_instance' is a reserved name." +msgstr "Додавання нового поля: ім'я 'field_instance' - зарезервовано" + +msgid "Add new field: the field name %field_name already exists." +msgstr "Додавання нового поля: ім'я поля %field_name зайняте" + +msgid "Add new field: you need to select a field type." +msgstr "Додавання нового поля: потрібно обрати тип поля" + +msgid "Add new field: you need to select a widget." +msgstr "Додавання нового поля: вам потрібно обрати візитку" + +msgid "Add new field: invalid widget." +msgstr "Додавання нового поля: некоректна візитка" + +msgid "Add existing field: you need to provide a label." +msgstr "Існуюче поле: Вам потрібно вказати мітку" + +msgid "Add existing field: you need to select a field." +msgstr "Існуюче поле: Вам потрібно обрати поле" + +msgid "Add existing field: you need to select a widget." +msgstr "Існуюче поле: Вам потрібно обрати візитку" + +msgid "Add existing field: invalid widget." +msgstr "Існуюче поле: некоректна візитка" + +msgid "The field %label cannot be added to a content type because it is locked." +msgstr "Поле %label неможливо додати бо тип матеріалу заблокований" + +msgid "There are no fields configured for this content type. You can add new fields on the <a href=\"@link\">Manage fields</a> page." +msgstr "Відсутні поля для даного типу матеріалів. Ви можете додавати нові поля на сторінці <a href=\"@link\">Керування полями</a>" + +msgid "@type: @field (@label)" +msgstr "@type: @field (@label)" + +msgid "Edit basic information" +msgstr "Зміна базової інформації" + +msgid "The machine-readable name of the field. This name cannot be changed." +msgstr "Комп'ютерне ім'я поля. Змінити неможливо" + +msgid "A human-readable name to be used as the label for this field in the %type content type." +msgstr "Людиноподібне ім'я, що буде використано як мітка для цього поля в типі матеріалу %type" + +msgid "The type of data you would like to store in the database with this field. This option cannot be changed." +msgstr "Тип даних, що бажаєте зберігати в базі даних з допомогою цього поля. Дана операція не може бути змінена." + +msgid "The type of form element you would like to present to the user when creating this field in the %type content type." +msgstr "Тип елемента форми, що хочете відобразити користувачу, коли створюється це поле в типі матеріалу %type" + +msgid "Updated basic settings for field %label." +msgstr "Оновлено базові параметри для поля %label." + +msgid "There was a problem updating the basic settings for field %label." +msgstr "Виникла проблема оновлення базових параметрів для поля %label." + +msgid "This field is <strong>locked</strong> and cannot be removed." +msgstr "Поле <strong>заблоковане</strong> і не може бути видалене" + +msgid "The field %field is locked and cannot be edited." +msgstr "Поле %field заблоковане і не може бути зміненим" + +msgid "%type basic information" +msgstr "%type базова інформація" + +msgid "Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>To figure out the expected format, you can use the <em>devel load</em> tab provided by <a href=\"@link_devel\">devel module</a> on a %type content page." +msgstr "Лише для досвідчених користувачів: код PHP, що надає значення за замовчуванням. Не повинен містити розмежовувачів <?php ?>. Якщо це поле заповнене, значення, надане цим кодом замістить будь-яке значення, вказане вгорі. Очікуваний формат: <pre>!sample</pre>Для визначення очікуваного формату ви можете скористатись закладкою <em>devel load</em>, наданою <a href=\"@link_devel\">devel module</a> на сторінці контенту %type." + +msgid "Maximum number of values users can enter for this field." +msgstr "Максимальна кількість значень, що користувачі можуть вносити для цього поля" + +msgid "'Unlimited' will provide an 'Add more' button so the users can add as many values as they like." +msgstr "'Необмежено' створить кнопку 'Додати ще', а отже користувачі зможуть додати скільки завгожно власних значенб" + +msgid "The PHP code for 'default value' returned @value, which is invalid." +msgstr "Код PHP для 'базового значення' повернув @value, що є некоректним" + +msgid "%name must be an integer." +msgstr "%name повинно бути цілим" + +msgid "%name must be a positive integer." +msgstr "%name повинно бути позитивним цілим" + +msgid "%name must be a number." +msgstr "%name повинно бути номером" + +msgid "You should make sure that the used field exists in the given content type." +msgstr "Вам потрібно впевнитись, що використовуване поле наявне в даному типі матеріалу" + +msgid "Advanced: Specify the fields value with PHP code" +msgstr "Розширене: Вкажіть значення полей кодом PHP" + +msgid "Advanced usage only: PHP code that returns the value to set. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format: <pre>!sample</pre>Using <a href=\"@link_devel\">devel.module's</a> 'devel load' tab on a content page might help you figure out the expected format." +msgstr "Лише для досвідчених користувачів: код PHP, що надає значення для встановлення. Не повинен містити <?php ?> розмежовувачів. Якщо це поле заповнене, значення, надане цим кодом замістить будь-яке значення, вказане вгорі. Очікуваний формат: <pre>!sample</pre>Використання закладки <a href=\"@link_devel\">devel.module's</a> 'devel load' на сторінці контенту може допомогти вам зрозуміти очікуваний формат." + +msgid "You have to return the default value in the expected format." +msgstr "Потрібно повертати базове значення в передбаченому форматі" + +msgid "Populate @node's field '@field'" +msgstr "Заповнення поля '@field' матеріалу @node" + +msgid "Field has value" +msgstr "Поле має значення" + +msgid "You should make sure that the used field exists in the given content type. The condition returns TRUE, if the selected field has the given value." +msgstr "Вам потрібно переконатись, що дані поля наявні в вказаному типі матеріалу. Повертається TRUE, якщо обрані поля мають вказане значення." + +msgid "Field has changed" +msgstr "Поле змінено" + +msgid "Content containing changes" +msgstr "Матеріал містить зміни" + +msgid "Content not containing changes" +msgstr "Матеріал без змін" + +msgid "@node's field '@field' has value" +msgstr "поле @node '@field' має значення" + +msgid "Select the machine-name of the field to look at." +msgstr "Вибір комп'ютерного імені показаному полю" + +msgid "@node's field '@field' has been changed" +msgstr "Змінено поле '@field' матеріалу @node" + +msgid "Referenced node unfiltered title. WARNING - raw user input." +msgstr "Нефільтрований заголовок пов'язаного матеріалу. Увага - чистий ввід вмд користувача!" + +msgid "Formatted html link to the referenced node." +msgstr "Форматоване HTML посилання до пов'язаного матеріалу" + +msgid "Relative path alias to the referenced node." +msgstr "Відносна адреса до пов'язаного матеріалу" + +msgid "Absolute path alias to the referenced node." +msgstr "Абсолютна адреса до пов'язаного матеріалу" + +msgid "Relative path alias to the referenced user." +msgstr "ВІдносна адреса до пов'язаного користувача" + +msgid "Absolute path alias to the referenced user." +msgstr "Абсолютна адреса до пов'язаного користувача" + +msgid "Field: @widget_label (@field_name) - @field_type" +msgstr "" + +msgid "Field on the referenced node." +msgstr "" + +msgid "Configure how the label is going to be displayed. This option takes no effect when \"Override title\" option is enabled, the specified block title is displayed instead." +msgstr "" + +msgid "Field formatter" +msgstr "" + +msgid "Select a formatter." +msgstr "" + +msgid "\"@s\" field: @widget_label (@field_name) - @field_type" +msgstr "" + +msgid "@label (!name)" +msgstr "@label (!name)" + +msgid "@label (!name) - !column" +msgstr "@label (!name) - !column" + +msgid "@label-truncated - !column" +msgstr "@label-скорочена - !column" + +msgid "Appears in: @types" +msgstr "Використана в: @types" + +msgid "<No value>" +msgstr "<Без значення>" + +msgid "Widget label (@label)" +msgstr "Мітка Візитки (@label)" + +msgid "Custom label" +msgstr "Своя мітка" + +msgid "(first item is 0)" +msgstr "" + +msgid "(start from last values)" +msgstr "" + +msgid "The delta allows you to select which item in a multiple value field to key the relationship off of. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "Допустима похибка дозволяє вам обрати, який елемент в полі з декількома значеннями буде відмикати взаємозв'язок. Оберіть \"1\" для використання першого елемента, \"2\" для другого елемента, і так далі. Якщо ви оберете \"All\", кожен елемент у полі створить новий рядок, що, можливо, створить копії." + +msgid "The delta allows you to select which item in a multiple value field will be used for sorting. Select \"1\" to use the first item, \"2\" for the second item, and so on. If you select \"All\", each item in the field will create a new row, which may appear to cause duplicates." +msgstr "Допустима похибка дозволяє вам обрати, який елемент в полі з декількома значеннями буде використовуватись для сортування. Оберіть \"1\" для використання першого елемента, \"2\" для другого елемента, і так далі. Якщо ви оберете \"All\", кожен елемент у полі створить новий рядок, що, можливо, створить копії." + +msgid "You need to provide a label." +msgstr "Необхідно вказати мітку" + +msgid "You need to provide a group name." +msgstr "Необхідно вказати ім'я групи" + +msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores." +msgstr "Назва групи %group_name недійсна. Назва має містити лише малі ненаголошені літери, цифри та підкреслення." + +msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix." +msgstr "Назва групи %group_name занадто довга. Назва обмежена 32 символами, включаючи префікс 'group_'." + +msgid "The group name %group_name already exists." +msgstr "Назва групи %group_name вже існує." + +msgid "Add new group:" +msgstr "Додати нову групу:" + +msgid "Add new group: you need to provide a label." +msgstr "Додати нову групу: потрібно вказати мітку." + +msgid "Add new group: you need to provide a group name." +msgstr "Додати нову групу: потрібно вказати ім'я групи" + +msgid "Standard group" +msgstr "Стандартна група" + +msgid "Create display groups for CCK fields." +msgstr "Створення групи відображення полів CCK" + +msgid "Field group: @group in @type" +msgstr "" + +msgid "All fields from this field group on the referenced node." +msgstr "" + +msgid "Field group label" +msgstr "" + +msgid "Configure how the field group label is going to be displayed. This option takes no effect when \"Override title\" option is enabled, the specified block title is displayed instead." +msgstr "" + +msgid "Fieldset - Collapsible" +msgstr "" + +msgid "Fieldset - Collapsed" +msgstr "" + +msgid "Field group format" +msgstr "" + +msgid "This option allows you to configure the field group format." +msgstr "" + +msgid "\"@s\" field group: @group in @type" +msgstr "" + +msgid "Note that if the field has multiple values, only the first content node will be loaded." +msgstr "Відмітьте, що якщо поле містить численні значення, лише перший вузол контенту буде завантажено." + +msgid "There are no nodereference fields defined." +msgstr "Не визначено жодного поля довідки вузлів." + +msgid "<p>Choose the \"Views module\" view that selects the nodes that can be referenced.<br />Note:</p>" +msgstr "" + +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>" +msgstr "" + +msgid "<p>The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +msgid "%name: invalid input." +msgstr "%name: неправильне введення" + +msgid "%name: found no valid post with that title." +msgstr "%name: не знайдено дійсного повідомлення з таким заголовком." + +msgid "Only numbers and decimals are allowed in %field." +msgstr "Тільки числа і десяткові значення дозволені в полі %field." + +msgid "Only numbers are allowed in %field." +msgstr "Тільки числа дозволені в полі %field." + +msgid "Only numbers and the decimal character (%decimal) are allowed in %field." +msgstr "Лише цифри та знак дробу (%decimal) дозволені в %field." + +msgid "Note that if the field has multiple values, only the first user will be loaded." +msgstr "Відмітьте, що якщо у поля є численні значення, завантажиться лише перший користувач." + +msgid "There are no userreference fields defined." +msgstr "Немає зазначених полей пов'язаного користувача" + +msgid "Advanced - Users that can be referenced (View)" +msgstr "Розширено - Користувачі, що можуть бути пов'язані (Вигляд)" + +msgid "View used to select the users" +msgstr "Вигляд використано для вибору користувачів" + +msgid "<p>Choose the \"Views module\" view that selects the users that can be referenced.<br />Note:</p>" +msgstr "" + +msgid "<ul><li>Only views that have fields will work for this purpose.</li><li>This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.</li></ul>" +msgstr "" + +msgid "<p>The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. <br />Note:</p>" +msgstr "" + +msgid "%name: invalid user." +msgstr "%name: некоректний користувач." + +msgid "New field" +msgstr "Нове поле" + +msgid "Existing field" +msgstr "Існуюче поле" + +msgid "New group" +msgstr "Нова група" + +msgid "Add fields and groups to the content type, and arrange them on content display and input forms." +msgstr "Додати поля та групи до типу контенту, і впорядкувати їх на єкранах контенту та формах введення." + +msgid "You can add a field to a group by dragging it below and to the right of the group." +msgstr "Ви можете додати поле до групи, перетянувши його вниз і вправо від групи." + +msgid "Note: Installing the <a href=\"!adv_help\">Advanced help</a> module will let you access more and better help." +msgstr "Зверніть увагу: Встановлення модуля <a href=\"!adv_help\">Advanced help</a> дозволить вам звертатись за більш обсяжною та точнішою допомогою." + +msgid "Use the 'Exclude' checkbox to exclude an item from the !content value passed to the node template." +msgstr "Користуйтесь відміткою 'виключити' для виключення елемента з значення !content, переданого до шаблону вузла." + diff --git a/drupal/sites/default/boinc/modules/contrib/cck/translations/vi.po b/drupal/sites/default/boinc/modules/contrib/cck/translations/vi.po new file mode 100644 index 0000000000000000000000000000000000000000..084ec6d20e182d1473b4ae8c75dde260845400f7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/cck/translations/vi.po @@ -0,0 +1,417 @@ +# $Id$ +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# field.php,v 1.3 2006/04/16 13:47:13 JonBob +# text.module,v 1.34 2006/06/12 19:59:53 JonBob +# number.module,v 1.29 2006/07/11 00:15:06 JonBob +# content_admin.inc,v 1.16 2006/06/12 19:36:54 JonBob +# content.module,v 1.65 2006/07/11 00:18:20 JonBob +# nodereference.module,v 1.28 2006/06/12 19:36:54 JonBob +# optionwidgets.module,v 1.8 2006/05/01 15:45:29 JonBob +# userreference.module,v 1.24 2006/05/05 14:10:44 JonBob +# weburl.module,v 1.8 2006/06/12 19:36:54 JonBob +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2006-07-27 08:09-0400\n" +"PO-Revision-Date: 2007-01-03 00:19+0700\n" +"Last-Translator: thehongtt <thehongtt@yahoo.com>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: content.module:18 +msgid "Allows administrators to define new content types." +msgstr "Cho phép người điều h`nh định nghĩa các kiểu nội dung mới." + +#: content.module:73 +msgid "add content type" +msgstr "thêm kiểu dữ liệu" + +#: content.module:80 +msgid "fields" +msgstr "các trường" + +#: content.module:119 +#: content_admin.inc:25 +msgid "duplicate" +msgstr "tạo bản sao" + +#: content.module:135 +msgid "manage fields" +msgstr "quản lý các trường" + +#: content.module:164 +msgid "remove field" +msgstr "xóa trường" + +#: content_admin.inc:42 +msgid "Content types" +msgstr "Các kiểu nội dung" + +#: content_admin.inc:90 +msgid "The human-readable name of this content type." +msgstr "Tên của kiểu nội dung có thể đọc được." + +#: content_admin.inc:98 +msgid "A brief description of the content type." +msgstr "Mô tả ngắn cho kiểu nội dung." + +#: content_admin.inc:106 +msgid "Instructions to present to the user when adding new content of this type." +msgstr "Lời hướng dẫn được hiển thị cho người dùng khi họ thêm một nội dung mới với kiểu nội dung n`y." + +#: content_admin.inc:110 +msgid "Title field label" +msgstr "Title field label" + +#: content_admin.inc:113 +msgid "The label for the title field." +msgstr "Nhãn cho tiêu đề của trường." + +#: content_admin.inc:118 +msgid "Save content type" +msgstr "Lưu kiểu nội dung" + +#: content_admin.inc:182 +msgid "Saved content type %type." +msgstr "Đã lưu kiểu nội dung %type" + +#: content_admin.inc:198 +msgid "Are you sure you want to delete the content type %type?" +msgstr "Bạn thật sự muốn xóa kiểu nội dung %type?" + +#: content_admin.inc:198 +msgid "If you have any content left in this content type, it will be permanently deleted. This action cannot be undone." +msgstr "Nếu bạn có nội dung n`o không xuất hiện trong kiểu nội dung n`y, nó sẽ bị xóa. Thao tác n`y không thể được ho`n lại." + +#: content_admin.inc:218 +msgid "Deleted content type %type." +msgstr "Đã xóa kiểu nội dung %type" + +#: content_admin.inc:248 +msgid "remove" +msgstr "xóa" + +#: content_admin.inc:277 +msgid "Add existing field" +msgstr "Thêm trường đã tồn tại" + +#: content_admin.inc:286 +msgid "Add field" +msgstr "Thêm trường" + +#: content_admin.inc:307 +msgid "Create new field" +msgstr "Tạo trường mới" + +#: content_admin.inc:313 +msgid "The human-readable name of this field." +msgstr "Tên có thể đọc cho trường n`y." + +#: content_admin.inc:318 +msgid "Field type" +msgstr "Kiểu trường" + +#: content_admin.inc:326 +msgid "Create field" +msgstr "Tạo trường" + +#: content_admin.inc:335 +msgid "No field modules are enabled. You need to <a href=\"%modules_url\">enable one</a>, such as text.module, before you can add new fields." +msgstr "Không có module tạo ra trường n`o. Bạn cần <a href=\"%modules_url\">kích hoạt một</a>, như l` text.module, trước khi bạn có thể thêm v`o các trường." + +#: content_admin.inc:389 +msgid "Added field %label." +msgstr "Đã thêm trường %label." + +#: content_admin.inc:432 +msgid "Created field %label." +msgstr "Đã tạo trường %label." + +#: content_admin.inc:452 +msgid "Are you sure you want to remove the field %field?" +msgstr "Bạn thật sự muốn xóa trường $field?" + +#: content_admin.inc:452 +msgid "If you have any content left in this field, it will be lost. This action cannot be undone." +msgstr "Nếu bạn có nội dung n`o không có ở trong trường n`y, nó sẽ bị mất đi. Thao tác n`y không thể ho`n lại." + +#: content_admin.inc:452 +msgid "Remove" +msgstr "Xóa" + +#: content_admin.inc:468 +msgid "Removed field %field from %type." +msgstr "Đã xóa trường %field khỏi %type" + +#: content_admin.inc:487 +msgid "The field %field no longer exists in any content type, so it was deleted." +msgstr "Trường %field không còn tồn tại trong kiểu nội dung n`o, vì thế nó đã bị xóa." + +#: content_admin.inc:511 +msgid "Widget settings" +msgstr "Các thiết lập widget" + +#: content_admin.inc:512 +msgid "These settings apply only to the %field field as it appears in the %type content type." +msgstr "Những thiết lập chỉ áp dụng cho trường %field khi nó hiển thị ở kiểu nội dung %type." + +#: content_admin.inc:526 +msgid "Widget" +msgstr "Widget" + +#: content_admin.inc:541 +msgid "In the node editing form, the heavier fields will sink and the lighter fields will be positioned nearer the top." +msgstr "Trong form soạn thảo node, những trường nặng hơn sẽ chìm xuống v` những trường nhẹ hơn sẽ nổi lên phía trên." + +#: content_admin.inc:552 +msgid "Instructions to present to the user below this field on the editing form." +msgstr "Lời hướng dẫn cho người dùng sẽ được hiển thị ở phía dưới trường trong trang biên soạn." + +#: content_admin.inc:558 +msgid "Data settings" +msgstr "Các thiết lập dữ liệu" + +#: content_admin.inc:559 +msgid "These settings apply to the %field field in every content type in which it appears." +msgstr "Các thiết lập n`y áp dụng v`o trường %field trong mỗi kiểu nội dung m` nó xuất hiện." + +#: content_admin.inc:568 +msgid "Multiple values" +msgstr "Nhiều giá trị" + +#: content_admin.inc:579 +msgid "Save field settings" +msgstr "Lưu các thiết lập của trường" + +#: content_admin.inc:652 +msgid "Saved field %field." +msgstr "Đã lưu trường %field" + +#: content_admin.inc:16;87;232;310;533 +msgid "Label" +msgstr "Nhãn" + +#: content_admin.inc:882;971 +msgid "No PostgreSQL mapping found for %type data type." +msgstr "Không tìm thấy PostgreSQL mapping cho kiểu dữ liệu %type." + +#: content_admin.inc:882;971 +msgid "database" +msgstr "cơ sở dữ liệu" + +#: date.module:15 +msgid "Defines a date/time field type. <em>Note: Requires content.module.</em>" +msgstr "Định nghĩa một kiểu trường ng`y/giờ. <em>Chú ý: Yêu cầu content.module.</em>" + +#: date.module:36 +msgid "Year" +msgstr "Năm" + +#: date.module:37 +msgid "Year and month" +msgstr "Năm v` tháng" + +#: date.module:39 +msgid "Date and time" +msgstr "Ng`y v` giờ" + +#: date.module:43 +msgid "Granularity" +msgstr "Granularity" + +#: date.module:101 +msgid "Times are entered and displayed with site's time zone" +msgstr "Thời gian được gán v`o v` trình b`y ứng với muối giờ của người dùng." + +#: date.module:102 +msgid "Times are entered and displayed with user's time zone" +msgstr "Thời gian được gán v`o v` trình b`y ứng với muối giờ của người dùng." + +#: date.module:106 +msgid "Time zone handling" +msgstr "Thao tác với các muối giờ." + +#: date.module:154 +msgid "%name must be entered in ISO 8601 format (YYYY)." +msgstr "%name phải được gán với định dạng ISO 8601 (YYYY-MM-DD)." + +#: date.module:159 +msgid "%name must be entered in ISO 8601 format (YYYY-MM)." +msgstr "%name phải được gán với định dạng ISO 8601 (YYYY-MM-DD)." + +#: date.module:164 +msgid "%name must be entered in ISO 8601 format (YYYY-MM-DD)." +msgstr "%name phải được gán với định dạng ISO 8601 (YYYY-MM-DD)." + +#: date.module:169 +msgid "%name must be entered in ISO 8601 format (YYYY-MM-DDThh:mm:ss)." +msgstr "%name phải được gán với định dạng ISO 8601 (YYY-MM-DD)." + +#: field.php:77 +#: text.module:44 +msgid "Maximum length" +msgstr "Độ d`i tối đa" + +#: field.php:80 +#: text.module:47 +msgid "The maximum length of the field in characters. Leave blank for an unlimited size." +msgstr "Số ký tự tối đa cho trường. Để trống nếu muốn độ d`i l` vô hạn." + +#: field.php:102 +#: number.module:82 +#: text.module:80 +msgid "is equal to" +msgstr "bằng với" + +#: field.php:103 +#: number.module:83 +#: text.module:81 +msgid "is not equal to" +msgstr "không bằng với" + +#: field.php:104 +#: text.module:82 +msgid "matches the pattern" +msgstr "khớp với mẫu" + +#: field.php:265 +#: text.module:159 +msgid "Rows" +msgstr "Số dòng" + +#: field.php:273 +#: text.module:167 +msgid "\"Rows\" must be a positive integer." +msgstr "\"Số dòng\" phải l` một số nguyên dương." + +#: field.php:180;190 +#: number.module:119 +#: text.module:107 +msgid "Illegal value for %name." +msgstr "Giá trị cho %name không hợp lệ." + +#: nodereference.module:0 +msgid "nodereference" +msgstr "nodereference" + +#: nodereference.module:15 +msgid "Defines a field type for referencing one node from another. <em>Note: Requires content.module.</em>" +msgstr "Định nghĩa một kiểu trường để tham khảo đến một node từ một node khác. <em>Chú ý: yêu cầu content.module.</em>" + +#: nodereference.module:26 +msgid "node reference autocomplete" +msgstr "tham khảo node tự động ho`n th`nh" + +#: nodereference.module:51 +msgid "Content types that can be referenced" +msgstr "Những kiểu nội dung có thể được tham khảo đến" + +#: nodereference.module:204 +msgid "No post with that title exists." +msgstr "Không tồn tại b`i viết n`o với tiêu đề đó." + +#: number.module:0 +msgid "number" +msgstr "số" + +#: number.module:15 +msgid "Defines numeric field types. <em>Note: Requires content.module.</em>" +msgstr "Định nghĩa các kiểu trường số. <em>Chú ý: Yêu cầu content.module.</em>" + +#: number.module:38 +msgid "Minimum" +msgstr "Tối thiểu" + +#: number.module:43 +msgid "Maximum" +msgstr "Tối đa" + +#: number.module:48 +#: text.module:51 +msgid "Allowed values" +msgstr "Các giá trị cho phép" + +#: number.module:52 +#: text.module:55 +msgid "The possible values this field can contain. Any other values will result in an error. Enter one value per line." +msgstr "Những giá trị m` trường n`y có thể mang. Những giá trị khác sẽ trả về lỗi. Điền mỗi giá trị v`o mỗi dòng." + +#: number.module:58 +msgid "\"Minimum\" must be a number." +msgstr "\"Tối thiểu\" phải l` một con số." + +#: number.module:61 +msgid "\"Maximum\" must be a number." +msgstr "\"Tối đa\" phải l` một con số." + +#: number.module:113 +msgid "The value of %name may be no smaller than %min." +msgstr "Giá trị của %name không thể nhỏ hơn %min." + +#: number.module:116 +msgid "The value of %name may be no larger than %max." +msgstr "Giá trị của %name không thể lớn hớn %max." + +#: optionwidgets.module:0 +msgid "optionwidgets" +msgstr "optionwidgets" + +#: optionwidgets.module:15 +msgid "Defines selection, check box and radio button widgets for text and numeric fields. <em>Note: Requires content.module, text.module and number.module.</em>" +msgstr "Định nghĩa hộp select, checkbox v` nút radio cho văn bản v` các trường số. <em>Chú ý: Yêu cầu content.module, text.module v` number.module.</em>" + +#: text.module:0 +msgid "text" +msgstr "ký tự" + +#: text.module:15 +msgid "Defines simple text field types. <em>Note: Requires content.module.</em>" +msgstr "Định nghĩa kiểu trường văn bản đơn giản. <em>Chú ý: Yêu cầu content.module.</em>" + +#: text.module:35 +msgid "Filtered text (user selects input format)" +msgstr "Văn bản được lọc (người dùng chọn định dạng dữ liệu v`o)" + +#: text.module:35 +msgid "Plain text" +msgstr "Ký tự đơn giản" + +#: text.module:38 +msgid "Text processing" +msgstr "Xử lý văn bản" + +#: text.module:144 +msgid "Text Field" +msgstr "Trường ký tự" + +#: userreference.module:0 +msgid "userreference" +msgstr "userreference" + +#: userreference.module:15 +msgid "Defines a field type for referencing a user from a node. <em>Note: Requires content.module.</em>" +msgstr "Định nghĩa kiểu trường để tham khảo một người dùng từ một node. <em>Chú ý: Yêu cầu content.module.</em>" + +#: userreference.module:176 +msgid "Invalid user name." +msgstr "Tên người dùng không hợp lệ." + +#: weburl.module:0 +msgid "weburl" +msgstr "weburl" + +#: weburl.module:15 +msgid "Defines simple weburl field types. <em>Note: Requires content.module.</em>" +msgstr "Định nghĩa các kiểu đường dẫn web đơn giản. <em>Chú ý: Yêu cầu content.module</em>" + +#: weburl.module:164;172 +msgid "Not a valid Web URL." +msgstr "Đường dẫn web không hợp lệ." + + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/LICENSE.txt b/drupal/sites/default/boinc/modules/contrib/content_profile/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..2c095c8d3f42488e8168f9710a4ffbfc4125a159 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/LICENSE.txt @@ -0,0 +1,274 @@ +GNU GENERAL PUBLIC LICENSE + + Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, +Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute +verbatim copies of this license document, but changing it is not allowed. + + Preamble + +The licenses for most software are designed to take away your freedom to +share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free software--to +make sure the software is free for all its users. This General Public License +applies to most of the Free Software Foundation's software and to any other +program whose authors commit to using it. (Some other Free Software +Foundation software is covered by the GNU Library General Public License +instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the +freedom to distribute copies of free software (and charge for this service if +you wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must make +sure that they, too, receive or can get the source code. And you must show +them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients +to know that what they have is not the original, so that any problems +introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + + 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 diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/README.txt b/drupal/sites/default/boinc/modules/contrib/content_profile/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..dc4d97c54883a16d3368b18f2540ccdc5a76610b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/README.txt @@ -0,0 +1,244 @@ +$Id: README.txt,v 1.1.2.11 2010/01/12 12:08:49 fago Exp $ + + +----------------------- +Content Profile Module +----------------------- +by Wolfgang Ziegler, nuppla@zites.net + +With this module you can build user profiles with drupal's content types. + + +Installation +------------ + * Copy the module's directory to your modules directory and activate the module. + + Usage: +-------- + * There will be a new content type "profile". Customize its settings at + admin/content/types. + * At the bottom of each content type edit form, there is a checkbox, which allows + you to mark a content type as profile. + * When you edit a profile content type there will be a further tab "Content profile", + which provides content profile specific settings. + + + Warning: +--------- + The module uses drupal's content or "nodes" for user profiles, so the access + permissions applied to view the content profiles are the regular node related + permissions. + That means the "access user profiles" permission of the user module still + applies only to the user account pages at "user/UID" but not to content profiles, + which can be viewed at node/NID too. Still you can use any regular node access + module to restrict access to your content profiles, e.g. you may use the Content + Access module for that (http://drupal.org/project/content_access). + + + +Content profiles per role: +-------------------------- +You may, but you need not, mark multiple content types as profile. By customizing +the permissions of a content type, this allows you to create different profiles for +different roles. + + +Hints: +------ + + * When using content profiles the "title" field is sometimes annoying. You can rename + it at the content types settings or hide it in the form and auto generate a title by + using the auto nodetitle module http://drupal.org/project/auto_nodetitle. + + * If you want to link to a content profile of a user, you can always link to the path + "user/UID/profile/TYPE" where UID is the users id and TYPE the machine readable content + type name, an example path would be "user/1/profile/profile". + This path is working regardless the user has already profile content created or not. + + * If you want to theme your content profile, you can do it like with any other content. + Read http://drupal.org/node/266817. + + * If you want a content profile to be private while your site content should be available + to the public, you need a module that allows configuring more fine grained access control + permissions, e.g. the module Content Access (http://drupal.org/project/content_access) + allows you to that. + + * There is also rules integration which is useful for customizing the behaviour of the + module. See below for more. + + + +Theming: Easily use profile information in your templates! +----------------------------------------------------------- +Content Profile adds a new variable $content_profile to most templates related to users. +So this variable allows easy access to the data contained in the users' profiles. +Furthermore it does its job fast by lazy-loading and caching the needed content profile +nodes. + +The $content_profile variable is available in the page, node, comment, user_name, +user_profile, user_signature, search_result and some other templates. + +$content_profile lets you access all variables of a profile, which are you used to +have in a common node template. See http://drupal.org/node/11816. + +So in any of these templates you may use the $content_profile like this: + +<?php + // Just output the title of the content profile of type 'profile' + // If there is no such profile, it will output nothing. + echo $content_profile->get_variable('profile', 'title'); + + // Get all variables of the content profile of type 'profile' + $variables = $content_profile->get_variables('profile'); + + // Print out a list of all available variables + // If the user has no profile created yet, $variables will be FALSE. + print_r($variables); + + if ($variables) { + // Print the title and the content. + echo $variables['title']; + echo $variables['content']; + } + else { + // No profile created yet. + } + + // $content_profile also allows you to easily display the usual content profile's view + // supporting the same parameters as node_view(). + echo $content_profile->get_view('profile'); + +?> + + Check the source of content_profile.theme_vars.inc to see what methods $content_profile + supports else. + + +Adding $content_profile to further templates +-------------------------------------------- + +If you miss $content_profile in some templates containing user information (id), just +fill a issue in content profile's queue so we can add it to the module. +Furthermore you may let content_profile its variable to your custom templates by specifying +the setting 'content_profile_extra_templates' in your site's settings.php. + +E.g. you may add: + $conf['content_profile_extra_templates'] = array('my_template'); + +Where 'my_template' has to be the key of your template's entry in the theme_registry (hook_theme()). + + + +Rules integration +------------------ + +There is some integration to the rules module (http://drupal.org/project/rules), which offers +a condition to check whether a user has already created a profile of a certain type. Then it +offers an action for loading the content profile of a user, which makes it available to token +replacements as well as to all other existing rules actions which deal with content. + +So this integration allows one to build some profile related rules with the rules module. As +example the module ships with one deactivated default rule: + + "Redirect to profile creation page, if users have no profile." + +If you activate it at the rules "Triggered rules" page, it's going to be evaluated when a user +logs in. Of course you can also alter the default rule and customize it so that it fits your needs, +e.g. you could remove the redirect action so that only a message is displayed. + + + + +--------------------------------------------- +Content Profile User Registration Integration +---------------------------------------------- + +There is a small extension module shipping with the main module, which allows one to enable +registration integration per content profile. + + +This module builds upon the main content profile module. It allows to integrate +the form of one or more content profile into the user registration page. + + +Installation +------------ + * Activiate the module. + * Be sure to read the usage notes below! + + + Usage: +-------- + * When you edit a profile content type there will be a further tab "Content profile", + which provides content profile specific settings. There is now a new field group + called "User Registration" which allows you to enable this feature for a content profile. + + * You need not grant anonymous users access to create the content profile. If you would do so, + anonymous users would be able to create anonymous profiles even without registering. + + * If you use the "Content permissions" module, which comes with CCK, make sure you grant access + to fields that should appear for anonymous users. + + * The weight of the profile (configurable at the content profile settings) controls the position + of the form elements on the registration page. + + * You may also hide some form elements at the settings. Basically it allows you to hide non-required + CCK fields as well as the title. If the title is hidden, it is set to the user's name. + + * For more control over the title use the "Automatic Nodetitles" module, which can be found + at http://drupal.org/project/auto_nodetitle. It integrates fine with this module. + + * Hiding required CCK fields is not supported, as the created content node would have empty + required fields afterwards, which in affect would make it impossible even for admins to edit + the content node. + + * So the "Hide other form elements" option allows you to hide all form elements not listed there, + but required CCK fields always stay. + + However, you can still hide required CCK fields by restricting anonymous access to them by using the + "Content permissions" module of CCK. But be aware of this issue - maybe also restrict access for + other roles accordingly. + + * If you want to hide the "body" field, just remove it from the content type in general at the content + type's settings page. Then instead of this, just create a CCK textfield, which can be hidden. + + * You can enable the registration integration for multiple profiles - however be aware that + shared form elements like the title only appear once and all created profile nodes get the same + values assigned. + + * For multiple registration paths for different roles, the AutoAssignRole module might help you: + http://drupal.org/project/autoassignrole. It comes with Content Profile Registration Integration, + so that you can select the profiles which should appear on each AutoAssignRole path (configurable + at the content profile settings). You'll need a version of AutoAssignRole released later than + June 4, 2009. + + * If you want to prepopulate some other form elements, maybe hidden CCK fields you can use the rules + module for that. See http://drupal.org/project/rules. + Just configure a rule, that reacts on the creation of the content profile (event) and populates + your fields value (action). + + * Putting file uploads on the registration form is not supported and probably won't work right. + + * The CCK "Add more fields" feature is only working for users with javascript turned on in the + registration form. Users without javascript won't be able to add more fields. Interested developers + can find the related issue (in drupal itself) here: http://drupal.org/node/634984 + + + +----------------------- +Content Profile Tokens +----------------------- + +Original author: @author Ádám Lippai - Oghma ltd. (lippai.adam@oghma.hu) + + +This is a small module that adds content profile tokens for textfields and number CCK fields for +a user as well as to the 'flag friend' modules' requester and requestee. + +Warning: This module slows down the generation of users tokens, thus it might have some performance + implications for your site. Use it with caution. + +Installation +------------ + * Activiate the module. + \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile-display-view.tpl.php b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile-display-view.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..8fb095ee7af904564c1a449ccb3d42e95bf33eb1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile-display-view.tpl.php @@ -0,0 +1,28 @@ +<?php +// $Id: content_profile-display-view.tpl.php,v 1.1.2.2 2009/01/04 11:46:29 fago Exp $ + +/** + * @file content-profile-display-view.tpl.php + * + * Theme implementation to display a content-profile. + */ +?> +<?php if (isset($title)): ?> + <h3 class="content-profile-title" id="content-profile-title-<?php print $type; ?>"> + <?php print $title; ?> + </h3> +<?php endif; ?> +<div class="content-profile-display" id="content-profile-display-<?php print $type; ?>"> + <?php if (isset($tabs)) : ?> + <ul class="tabs content-profile"> + <?php foreach ($tabs as $tab) : ?> + <?php if ($tab): ?> + <li><?php print $tab; ?></li> + <?php endif; ?> + <?php endforeach; ?> + </ul> + <?php endif; ?> + <?php if (isset($node->nid) && isset($content)): ?> + <?php print $content ?> + <?php endif; ?> +</div> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.css b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.css new file mode 100644 index 0000000000000000000000000000000000000000..19b2e0116d68e58f933937e7c85ac811e64ada9d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.css @@ -0,0 +1,21 @@ +@CHARSET "UTF-8"; + +div.content-profile-display { + border: 1px solid #DDD; + margin: 1em 0em; + padding: 0em 1em 1em 1em; +} + +ul.content-profile { + border-bottom: 1px solid #bbb; + padding: 0.5em 1em; +} + +ul.content-profile li { + display: inline; + padding: 0 2em; + border-right: 1px solid #ccc; + position: relative; + left: -1em; + background: none; +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.info b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.info new file mode 100644 index 0000000000000000000000000000000000000000..36cbcd298100a5889d6a2686c95668aa1b17d604 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.info @@ -0,0 +1,11 @@ +; $Id: content_profile.info,v 1.1.2.1 2008/02/01 16:00:24 fago Exp $ +name = "Content Profile" +description = "Use content types for user profiles." +package = "Content Profile" +core = 6.x +; Information added by drupal.org packaging script on 2010-04-07 +version = "6.x-1.0" +core = "6.x" +project = "content_profile" +datestamp = "1270662007" + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.install b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.install new file mode 100644 index 0000000000000000000000000000000000000000..9cfabe13c31672c283a76e25c4a7d22ea5bb127a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.install @@ -0,0 +1,139 @@ +<?php +// $Id: content_profile.install,v 1.1.2.7 2009/01/09 15:55:07 fago Exp $ +/** + * @file + * Content profile installation file. + */ + +/** + * Implementation of hook_enable(). + */ +function content_profile_enable() { + //enable the default content type 'profile' to be a content profile + $setting = variable_get('content_profile_profile', FALSE); + if (!$setting && $setting !== array()) { + variable_set('content_profile_profile', array()); + } +} + +/** + * Implementation of hook_install(). + */ +function content_profile_install() { + // Set the module weight to -1, so content_profile_user() gets called before + // node_user(), so that one can't set a node's uid to 0 on user deletion + // before the profile nodes are deleted. + db_query("UPDATE {system} SET weight = -1 WHERE name = 'content_profile'"); + + content_profile_import(); + + //create a profile type, if it doesn't exist yet + if (!node_get_types('type', 'profile')) { + $info = array( + 'type' => 'profile', + 'name' => t('Profile'), + 'module' => 'node', + 'description' => t('A user profile built as content.'), + 'locked' => FALSE, + 'custom' => TRUE, + ); + $info = _node_type_set_defaults($info); + node_type_save((object)$info); + } +} + +/** + * Import settings from nodeprofile / bio. + */ +function content_profile_import() { + //nodeprofile + if ($settings = variable_get('nodeprofile_settings', array())) { + $cp_setting = array(); + foreach ($settings as $setting => $data) { + foreach ($data as $type => $value) { + $cp_settings[$type][$setting] = $value; + } + } + foreach ($cp_settings as $type => $data) { + variable_set('content_profile_use_'. $type, 1); + $data['edit_tab'] = $data['user_edit'] ? 'sub' : 0; + unset($data['user_edit']); + variable_set('content_profile_'. $type, $data); + } + variable_del('nodeprofile_settings'); + } + //bio + if ($type = variable_get('bio_nodetype', FALSE)) { + variable_set('content_profile_use_'. $type, 1); + variable_del('bio_nodetype'); + } +} + +/** + * Implementation of hook_uninstall(). + */ +function content_profile_uninstall() { + foreach (node_get_types('names') as $typename => $visiblename) { + if (variable_get('content_profile_use'. $typename, 0)) { + variable_del('content_profile_use_'. $typename); + variable_del('content_profile_'. $typename); + } + } +} + +/** + * Set module weight to -1, as explained in content_profile_install(). + */ +function content_profile_update_6001() { + $ret = array(); + $ret[] = update_sql("UPDATE {system} SET weight = -1 WHERE name = 'content_profile'"); + return $ret; +} + + +/** + * Make the profile type to be "custom", so it can be deleted. + */ +function content_profile_update_6002() { + $ret = array(); + if (($type = node_get_types('type', 'profile')) && !$type->custom) { + $type->custom = TRUE; + node_type_save($type); + } + return $ret; +} + +/** + * Update the settings to reflect the changes of the format + * ('edit_link_sub' has been removed in favour of 'edit_tab') + */ +function content_profile_update_6003() { + $ret = array(); + drupal_load('module', 'content_profile'); + foreach (content_profile_get_types('names') as $type => $type_name) { + $settings = content_profile_get_settings($type); + if (!empty($settings['edit_link_sub'])) { + unset($settings['edit_link_sub']); + $settings['edit_tab'] = 'sub'; + content_profile_set_settings($type, $settings); + } + } + return $ret; +} + +/** + * Due to an old bug it may be that the $settings of a content type + * are '0'. As it should be an array this generates errors. + * This update fixes up those scrambled settings. + */ +function content_profile_update_6004() { + $ret = array(); + drupal_load('module', 'content_profile'); + foreach (node_get_types('names') as $type => $type_name) { + $settings = variable_get('content_profile_'. $type, array()); + if (!is_array($settings)) { + content_profile_set_settings($type, array()); + } + } + return $ret; +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.module b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.module new file mode 100644 index 0000000000000000000000000000000000000000..48bc9d2b8e1bf540fa11c4eef6d09355ca3f90a2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.module @@ -0,0 +1,649 @@ +<?php +// $Id: content_profile.module,v 1.1.2.48 2010/04/07 15:09:17 fago Exp $ + +/** + * @file + * Marks content types as profiles. + */ + + +/** + * Implementation of hook_init(). + */ +function content_profile_init() { + module_load_include('inc', 'content_profile', 'content_profile.theme_vars'); +} + +/** + * Implementation of hook_ctools_plugin_directory(). + */ +function content_profile_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && $plugin == 'relationships') { + return 'panels/' . $plugin; + } +} + +/** + * Implementation of hook_menu(). + */ +function content_profile_menu() { + $items = array(); + + //Register a path for each content profile type + foreach (content_profile_get_types('names') as $type => $typename) { + $items['admin/content/node-type/'. str_replace('_', '-', $type) .'/edit'] = array( + 'title' => 'Edit', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items['admin/content/node-type/'. str_replace('_', '-', $type) .'/profile'] = array( + 'title' => 'Content profile', + 'description' => 'Configure the display and management of this content profile.', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('content_profile_admin_settings', $type), + 'access callback' => 'user_access', + 'access arguments' => array('administer nodes'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 1, + ); + } + foreach (content_profile_get_types('names') as $type => $type_name) { + $items['user/%user/profile/'. $type] = array( + 'title callback' => 'check_plain', + 'title' => drupal_ucfirst($type_name), + 'page callback' => 'content_profile_page_edit', + 'page arguments' => array($type, 1), + 'access callback' => 'content_profile_page_access', + 'access arguments' => array($type, 1), + 'weight' => content_profile_get_settings($type, 'weight'), + 'file' => 'node.pages.inc', + 'file path' => drupal_get_path('module', 'node'), + 'type' => content_profile_get_settings($type, 'edit_tab') == 'top' ? MENU_LOCAL_TASK : MENU_CALLBACK, + ); + } + return $items; +} + +/** + * Implementation of hook_menu_alter(). + * Take over menu items generated by the user module for our categories. + */ +function content_profile_menu_alter(&$items) { + foreach (content_profile_get_types('names', 'edit_tab', 'sub') as $type => $type_name) { + if (!empty($items['user/%user_category/edit/'. $type])) { + $item = &$items['user/%user_category/edit/'. $type]; + $item = array( + 'page callback' => 'content_profile_page_edit', + 'page arguments' => array($type, 1), + 'access callback' => 'content_profile_page_access', + 'access arguments' => array($type, 1), + 'file' => 'node.pages.inc', + 'file path' => drupal_get_path('module', 'node'), + ) + $item; + } + } +} + + +function content_profile_page_access($type, $account) { + if ($node = content_profile_load($type, $account->uid)) { + return node_access('update', $node); + } + // Else user may view the page when they are going to create their own profile + // or have permission to create it for others. + global $user; + if ($user->uid == $account->uid || user_access('administer nodes') ){ + return node_access('create', $type); + } + return FALSE; +} + +/** + * Presents a node editing or adding form for the given content profile. + */ +function content_profile_page_edit($type, $account) { + drupal_set_title(check_plain($account->name)); + $node = content_profile_load($type, $account->uid); + if (!$node) { + $node = array('uid' => $account->uid, 'name' => (isset($account->name) ? $account->name : ''), 'type' => $type, 'language' => ''); + } + return drupal_get_form($type .'_node_form', $node); +} + + +/** + * Implementation of hook_views_api(). + */ +function content_profile_views_api() { + return array( + 'api' => 2, + 'path' => drupal_get_path('module', 'content_profile') .'/views', + ); +} + + +/** + * Menu callback; content profile settings. + */ +function content_profile_admin_settings(&$form_state, $type) { + $form_state['type'] = $type; + + $form['weight'] = array( + '#type' => 'weight', + '#title' => t("Weight"), + '#default_value' => content_profile_get_settings($type, 'weight'), + '#description' => t('The weight of content of this content type where ever they appear - this applies to the input form integration as well to the display integration.'), + '#weight' => 5, + ); + $form['display'] = array( + '#type' => 'fieldset', + '#title' => t('Display settings'), + '#description' => t('Customize the display of this content profile.'), + '#collapsible' => TRUE, + ); + $form['display']['user_display'] = array( + '#type' => 'radios', + '#title' => t("User page display style"), + '#default_value' => content_profile_get_settings($type, 'user_display'), + '#options' => array( + 0 => t("Don't display this content profile on the user account page"), + 'link' => t('Display it as link to the profile content'), + 'full' => t('Display the full content'), + 'teaser' => t("Display the content's teaser"), + ), + ); + $form['display']['edit_link'] = array( + '#type' => 'checkbox', + '#title' => t("Include an edit link to the display"), + '#default_value' => content_profile_get_settings($type, 'edit_link'), + ); + $form['display']['add_link'] = array( + '#type' => 'checkbox', + '#title' => t("Show a link to the content profile creation page, if there is no profile."), + '#default_value' => content_profile_get_settings($type, 'add_link'), + '#description' => t("If selected and the user has no profile of this type yet, a link to add one is shown on the user page."), + ); + $form['display']['edit_tab'] = array( + '#type' => 'radios', + '#title' => t("Profile edit tab"), + '#default_value' => content_profile_get_settings($type, 'edit_tab'), + '#options' => array( + 0 => t('None'), + 'top' => t("Show a tab at the user's page"), + 'sub' => t("Show a secondary tab below the user's edit tab"), + ), + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Submit'), + '#weight' => 10, + ); + return $form; +} + +function content_profile_admin_settings_submit($form, &$form_state) { + $settings = content_profile_get_settings($form_state['type']); + foreach (content_profile_settings_info() as $setting => $default) { + if (isset($form_state['values'][$setting])) { + $settings[$setting] = $form_state['values'][$setting]; + } + } + content_profile_set_settings($form_state['type'], $settings); + drupal_set_message('Your changes have been saved.'); + menu_rebuild(); +} + +/** + * Determine if a given node is a content_profile. + * @param $type + * The node object or the node's type + */ +function is_content_profile($type) { + if (is_object($type)) { + $type = $type->type; + } + return variable_get('content_profile_use_'. $type, FALSE); +} + +/** + * Builds a list of available content types that are marked as content_profiles, + * and returns an array of content profile content types in the specified format. + * + * @param $op + * When set to 'types', content profile content types are returned + * as type objects. When set to 'names', only their type names are returned. + * @param $setting + * If set, only content types that have this setting activated are returned. + * Leave it NULL to get all content profile types. + * @param $value + * The value to compare the given setting too. + */ +function content_profile_get_types($op = 'types', $setting = NULL , $value = TRUE) { + $types = array(); + + foreach (node_get_types($op) as $type => $info) { + if (is_content_profile($type) && (!isset($setting) || content_profile_get_settings($type, $setting) == $value)) { + $types[$type] = $info; + } + } + return $types; +} + +/** + * Implementation of hook_node_type(). + * Rename or delete the settings variable if a type changes. + */ +function content_profile_node_type($op, $info) { + switch ($op) { + case 'delete': + variable_del('content_profile_use_'. $info->type); + variable_del('content_profile_'. $info->type); + break; + case 'update': + if (!empty($info->old_type) && $info->old_type != $info->type) { + if (is_content_profile($info->old_type)) { + $settings = variable_get('content_profile_'. $info->old_type, array()); + variable_del('content_profile_use_'. $info->old_type); + variable_del('content_profile_'. $info->old_type); + variable_set('content_profile_use_'. $info->type, 1); + variable_set('content_profile_'. $info->type, $settings); + } + } + break; + } +} + +/** + * Implementation of hook_form_alter(). + */ +function content_profile_form_alter(&$form, $form_state, $form_id) { + if ($form_id == 'node_type_form') { + $form['content_profile'] = array( + '#type' => 'fieldset', + '#title' => t('Content Profile'), + '#group' => 'additional_settings', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#weight' => 32, + ); + $form['content_profile']['content_profile_use'] = array( + '#type' => 'checkbox', + '#title' => t('Use this content type as a content profile for users'), + '#default_value' => variable_get('content_profile_use_'. $form['#node_type']->type, FALSE), + ); + } + elseif (isset($form['#node']) && $form['#node']->type .'_node_form' == $form_id && is_content_profile($form['#node'])) { + // Customize the redirect target and buttons of our own node forms. + if (arg(0) == 'user' && is_numeric(arg(1)) && arg(2) == 'edit' || arg(2) == 'profile') { + $form['buttons']['preview']['#access'] = FALSE; + $form['buttons']['delete']['#access'] = FALSE; + $form['#redirect'] = arg(2) == 'profile' ? 'user/'. $form['#node']->uid : $_GET['q']; + } + // Set the author value - note that this works only for admins. + if (!empty($_GET['uid']) && ($uid = intval($_GET['uid'])) && ($user = user_load($uid))) { + $form['author']['name']['#default_value'] = $user->name; + } + } +} + +/** + * Implementation of hook_user(). + */ +function content_profile_user($op, &$edit, &$account, $category = NULL) { + global $user; + + switch ($op) { + case 'categories': + $data = array(); + foreach (content_profile_get_types('names', 'edit_tab', 'sub') as $type => $type_name) { + $data[] = array( + 'name' => $type, + 'title' => drupal_ucfirst($type_name), + 'weight' => content_profile_get_settings($type, 'weight') + 1, + ); + } + return $data; + + case 'view': + $account->content['content_profile'] = content_profile_show_profiles($account->uid); + break; + + case 'delete': + // Retrieve all profile nodes (in any language) for this user by issueing an SQL query. + if ($types = content_profile_get_types()) { + $condition = array_fill(0, count($types), "type = '%s'"); + $arguments = array_merge(array_keys($types), array($account->uid)); + + $result = db_query("SELECT * FROM {node} WHERE (". implode(' OR ', $condition) .") AND uid = %d", $arguments); + while ($node = db_fetch_object($result)) { + _content_profile_node_delete($node); + } + } + break; + } +} + +/** + * The original node_delete() function uses node_load() to get the $node object. + * Unfortunately, when a hook_user('delete') is called, node_load() doesn't + * work anymore because the user has already been deleted, and node_load() + * still expects the user to exist in the {user} table. + * + * So this is a modified copy of node_delete() that deletes a node without + * calling node_load(), taking the full $node object (as retrieved by a simple + * "SELECT * FROM {node}" query) instead of just the $nid. + */ +function _content_profile_node_delete($node) { + // Copied over from node_load(), so that node_invoke('delete') gets + // the fully extended node object, like modules would expect: + + if ($node->nid) { + // Call the node specific callback (if any) and piggy-back the + // results to the node or overwrite some values. + if ($extra = node_invoke($node, 'load')) { + foreach ($extra as $key => $value) { + $node->$key = $value; + } + } + if ($extra = node_invoke_nodeapi($node, 'load')) { + foreach ($extra as $key => $value) { + $node->$key = $value; + } + } + } + + // Copied over from node_delete(): + + db_query('DELETE FROM {node} WHERE nid = %d', $node->nid); + db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid); + + // Call the node-specific callback (if any): + node_invoke($node, 'delete'); + node_invoke_nodeapi($node, 'delete'); + + // Clear the cache so an anonymous poster can see the node being deleted. + cache_clear_all(); + + // Remove this node from the search index if needed. + if (function_exists('search_wipe')) { + search_wipe($node->nid, 'node'); + } + watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title)); + drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_types('name', $node), '%title' => $node->title))); +} + +/** + * Implementation of hook_nodeapi(). + */ +function content_profile_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { + + if ($op == 'prepare' && is_content_profile($node) && !isset($node->nid) && $node->uid && !user_access('administer nodes') && arg(0) != 'admin') { + // Check if this nodetype already exists + if ($nid = content_profile_profile_exists($node, $node->uid)) { + // This node already exists, redirect to edit page + drupal_goto('node/'. $nid .'/edit', 'destination=user/'. $node->uid); + } + } + elseif ($op == 'validate' && is_content_profile($node) && user_access('administer nodes')) { + $form = $a3; + // Only validate if the user-name changed or we add a new node + if (!empty($node->nid) && $form['author']['name']['#default_value'] == $node->name) { + return; + } + //check whether the selected user has already a profile + $uid = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $node->name)); + if ($uid && content_profile_profile_exists($node, $uid)) { + form_set_error('name', t('This user already has a content profile of this type. You can only create one profile per user.')); + } + } + elseif ($op == 'prepare translation' && is_content_profile($node->translation_source)) { + // Make sure the translated profile belongs to the same user. + $node->uid = $node->translation_source->uid; + $node->name = $node->translation_source->name; + } +} + +/** + * Checks whether a node of this type exists already for the author + * + * @param $node + * The node, which is to be created. + * @param $uid + * The user to check for. + * @return If a node exists, the node id, FALSE else. + */ +function content_profile_profile_exists($node, $uid) { + $query = "SELECT n.nid AS nid FROM {node} n WHERE n.type = '%s' AND n.uid = %d "; + if (module_exists('translation') && translation_supported_type($node->type)) { + $query .= "AND n.language = '%s'"; + } + return db_result(db_query($query, $node->type, $uid, $node->language)); +} + +/** + * Returns the content_profiles' settings. + * @param $type + * The content type to return settings for. + * @param $return + * 'all' or one of the content_profile_available_settings(), + * e.g. user_edit, register or weight. + */ +function content_profile_get_settings($type, $return = 'all') { + $settings = variable_get('content_profile_'. $type, array()); + $settings += content_profile_settings_info(); + if ($return == 'all') { + return $settings; + } + return $settings[$return]; +} + +/** + * Saves the content_profile settings of a content type. + */ +function content_profile_set_settings($type, $settings) { + variable_set('content_profile_'. $type, $settings); +} + +/** + * Returns an array, which defines the available settings + * and their default value. + */ +function content_profile_settings_info() { + return module_invoke_all('content_profile_settings'); +} + +/** + * Implementation of hook_content_profile_settings(). + * + * Defines content profile settings and their default value. + */ +function content_profile_content_profile_settings() { + return array( + 'weight' => 0, + 'user_display' => 'full', + 'edit_link' => 0, + 'edit_tab' => 'sub', + 'add_link' => 1, + ); +} + +/** + * Loads the node, like node_load but makes sure the results are cached. + * + * @param $type + * The content profile's type. + * @param $uid + * The profile owner's user id. + * @param $lang + * Optional. If translation is enabled, the language of the profile to return. + * @param $reset + * Optional. If set, the cache is reset. + */ +function content_profile_load($type, $uid, $lang = '', $reset = NULL) { + static $cache = array(); + + if (!isset($cache[$type][$uid][$lang]) || $reset) { + $cache[$type][$uid][$lang] = FALSE; + $params = array('type' => $type, 'uid' => $uid); + if ($node = node_load($lang ? $params + array('language' => $lang) : $params, NULL, $reset)) { + $cache[$type][$uid][$lang] = $node->nid; + } + return $node; + } + return !empty($cache[$type][$uid][$lang]) ? node_load($cache[$type][$uid][$lang]) : FALSE; +} + +/** + * Implementation of hook_help(). + * + * Show node submission guidelines for content profile node forms. + */ +function content_profile_help($path, $arg) { + if (preg_match('/user\/\%\/(profile|edit)\/(.*)/', $path, $matches)) { + foreach (content_profile_get_types('names') as $type => $typename) { + if ($type == $matches[2]) { + $node = content_profile_load($type, $arg[1]); + if ($node) { + return node_help('node/%/edit', array(1 => $node->nid)); + } + else { + return node_help('node/add/'. $type, array('node', 'add', $type)); + } + } + } + } +} + +/** + * Returns an array suitable for use with drupal_render, + * that shows all content_profiles as configured by the admin. + */ +function content_profile_show_profiles($uid) { + global $user; + + $content = array(); + foreach (content_profile_get_types('names') as $type => $type_name) { + $node = content_profile_load($type, $uid); + + if (($style = content_profile_get_settings($type, 'user_display')) && $node && node_access('view', $node)) { + $content['content_profile_'. $type] = array( + '#theme' => ($style == 'link') ? 'content_profile_display_link' : 'content_profile_display_view', + '#edit_link' => content_profile_get_settings($type, 'edit_link'), + '#uid' => $uid, + '#style' => $style, + '#content_type' => $type, + '#weight' => content_profile_get_settings($type, 'weight'), + '#suffix' => '<br />', + ); + + // Working around the bug described at http://drupal.org/node/302873 + module_load_include('inc', 'content_profile', 'content_profile.theme'); + } + elseif (user_access('create '. $type .' content') && content_profile_get_settings($type, 'add_link') && !$node && ($uid == $user->uid || user_access('administer nodes'))) { + $content['content_profile_'. $type] = array( + '#admin' => $uid != $user->uid, + '#theme' => 'content_profile_display_add_link', + '#uid' => $uid, + '#content_type' => $type, + '#weight' => content_profile_get_settings($type, 'weight'), + '#suffix' => '<br />', + ); + } + } + if ($content) { + $content['#prefix'] = '<p id="content-profile-view">'; + $content['#suffix'] = '</p>'; + } + return $content; +} + +/** + * Implementation of hook_theme(). + */ +function content_profile_theme() { + $return = array( + 'content_profile_display_view' => array( + 'template' => 'content_profile-display-view', + 'arguments' => array('element' => NULL), + 'file' => 'content_profile.theme.inc', + ), + 'content_profile_display_add_link' => array( + 'file' => 'content_profile.theme.inc', + ), + 'content_profile_display_link' => array( + 'file' => 'content_profile.theme.inc', + ), + 'content_profile_display_tab_view' => array( + 'file' => 'content_profile.theme.inc', + ), + 'content_profile_display_tab_edit' => array( + 'file' => 'content_profile.theme.inc', + ), + ); + if (module_exists('pageroute')) { + $return['content_profile_pageroute_empty'] = array( + 'arguments' => array('type_name' => NULL), + 'file' => 'content_profile.pageroute.inc', + ); + } + return $return; +} + +/** + * Implementation of hook_theme_registry_alter(). + * Adds our own preprocess functions to some templates. Further templates can be set in + * $conf['content_profile_extra_templates'] in settings.php. + */ +function content_profile_theme_registry_alter(&$items) { + $templates = array_merge(array( + 'author_pane', + 'comment', + 'node', + 'page', + 'search_result', + 'username', + 'user_profile', + 'user_signature', + ), variable_get('content_profile_extra_templates', array())); + + foreach ($templates as $key) { + if (isset($items[$key])) { + $items[$key] += array('preprocess functions' => array()); + $items[$key]['preprocess functions'][] = 'content_profile_template_preprocess'; + } + } +} + +/** + * Adds $content_profile variable if we can find a $uid. + */ +function content_profile_template_preprocess(&$variables, $hook) { + // Search the uid + foreach (array('account_id', 'uid', 'account', 'node', 'comment', 'user') as $name) { + if (isset($variables[$name])) { + $uid = is_object($variables[$name]) ? $variables[$name]->uid : $variables[$name]; + $variables['content_profile'] = new content_profile_theme_variables($uid); + break; + } + } +} + +/** + * Implementation of hook_simpletest(). + */ +function content_profile_simpletest() { + // Scan through content_profile/tests directory for any .test files to tell SimpleTest module. + $tests = file_scan_directory(drupal_get_path('module', 'content_profile') .'/tests', '\.test'); + return array_keys($tests); +} + +/** + * Implementation of hook_pageroute_info() for Pageroute integration. + */ +function content_profile_pageroute_info() { + return array( + 'content_profile' => array( + 'viewprofile' => 'content_profile.pageroute', + 'editprofile' => 'content_profile.pageroute', + ) + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.pageroute.inc b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.pageroute.inc new file mode 100644 index 0000000000000000000000000000000000000000..ffc193fd27f1df5ee11423b7431ac66515ff9678 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.pageroute.inc @@ -0,0 +1,130 @@ +<?php +// $Id: content_profile.pageroute.inc,v 1.1.2.1 2010/01/12 13:50:39 fago Exp $ + +/** + * @file + * Pageroute intergration classes + */ + +include_once(drupal_get_path('module', 'pageroute') . '/pageroute.page_edit.inc'); +include_once(drupal_get_path('module', 'pageroute') . '/pageroute.page_view.inc'); + +/** + * theme_content_profile_pageroute_empty generates a message, if there is no content profile for the user. + */ +function theme_content_profile_pageroute_empty($type_name) { + return '<div class="content-profile-empty">'. + t('You have not created a @type yet. Go ahead and create one!', array('@type' => $type_name)) .'</div>'; +} + +/** + * ContentProfilePageEditProfile displays a form that allows users to edit content profiles. + */ +class ContentProfilePageEditProfile extends PageroutePageEdit { + + public function getForm(&$form, &$form_state, &$args) { + $args['hide_pageroute_buttons'] = FALSE; + $args['default_target'] = PAGEROUTE_CURRENT; + $page = &$form_state['page']; + + if (isset($form_state['node']) && $form_state['node']['type'] == $this->options['content-type']) { + $node = $form_state['node']; + } + else { + if (isset($page)) { + $node = node_load(array( + 'type' => $this->options['content-type'], + 'uid' => pageroute_page_get_uid($page), + )); + } + } + if (empty($node)) { + PageroutePageAdd::setNodeAddForm($form, $form_state, $page); + } + else { + $this->setNodeEditForm($form, $form_state, $page, $args, $node); + } + parent::unsetForm($form); + } + + public function getAdminForm($page, &$form) { + + $form['options']['content-type'] = array( + '#type' => 'select', + '#title' => t('Profile content type'), + '#options' => content_profile_get_types('names'), + '#default_value' => $page->options['content-type'], + '#weight' => 2, + '#description' => t('Select a content profile type.'), + ); + + PageroutePage::nodeUi($page, $form, TRUE); + } + + public static function help() { + return t('A page of this type will present a content profile node editing form of a configurable content-profile-type. It will edit the node with the id taken from the first argument of the pageroute. Furthermore this type can be configured to show a node adding form if the content profile is not existing. So you can build a pageroute that manages the creation and editing of content profiles.'); + } + + public static function info() { + return array('name' => t('Content profile editing form')); + } + + public function setUp() {} + + public static function getDefaultSubmitHandler($form) { + return 'node_form_submit'; + } + +} + +/** + * ContentProfilePageViewProfile displays a content profile. + */ +class ContentProfilePageViewProfile extends PageroutePageView { + /* + * Returns the page display for the configured node + */ + public function getForm(&$form, &$form_state, &$args) { + $page = &$form_state['page']; + + $args['hide_pageroute_buttons'] = FALSE; + $args['default_target'] = PAGEROUTE_CURRENT; + + $node = node_load(array( + 'type' => $page->options['content-type'], + 'uid' => pageroute_page_get_uid($page), + )); + + if ($node->nid && node_access('view', $node)) { + if (empty($this->title)) { + drupal_set_title(check_plain($node->title)); + } + node_tag_new($node->nid); + $form += array('pageroute-view' => array('#value' => node_view($node, FALSE, TRUE, FALSE))); + } + else { + $type_name = node_get_types('name', $page->options['content-type']); + $form += array('pageroute-view' => array('#value' => theme('content_profile_pageroute_empty', $type_name))); + } + } + + public function getAdminForm($page, &$form) { + $form['options']['content-type'] = array( + '#type' => 'select', + '#title' => t('Profile content type'), + '#options' => content_profile_get_types('names'), + '#required' => TRUE, + '#default_value' => $page->options['content-type'], + '#weight' => 2, + '#description' => t('You can only use content types marked as \'content profile\''), + ); + } + + public static function help() { + return t('The lonely node display page can be used to view this lonely node. This might be useful for displaying the lonely node aftercreation or update. There will be a (themeable) message if there is no node that can be displayed.'); + } + + public static function info() { + return array('name' => t('Content profile display')); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.rules.inc b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.rules.inc new file mode 100644 index 0000000000000000000000000000000000000000..8894a2cba377a879a3a22dbe3e5a9f284bf6ef34 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.rules.inc @@ -0,0 +1,97 @@ +<?php +// $Id: content_profile.rules.inc,v 1.1.2.2 2009/03/30 10:20:01 fago Exp $ + +/** + * @file + * Some rules conditions/actions + */ + +/** + * Implementation of hook_rules_condition_info(). + */ +function content_profile_rules_condition_info() { + return array( + 'content_profile_user_has_profile_condition' => array( + 'label' => t('User has content profile'), + 'arguments' => array( + 'user' => array('type' => 'user', 'label' => t('User')), + ), + 'module' => 'Content Profile', + ), + ); +} + +function content_profile_user_has_profile_condition($user, $settings) { + $node = content_profile_load($settings['type'], $user->uid); + return (bool)$node; +} + +function content_profile_user_has_profile_condition_form($settings, &$form) { + $settings += array('type' => array()); + $form['settings']['type'] = array( + '#type' => 'select', + '#title' => t('Content Profile Content Type'), + '#options' => content_profile_get_types('names'), + '#default_value' => $settings['type'], + '#description' => t('Select the Content Profile content type to check for.'), + '#required' => TRUE, + ); +} + +function content_profile_user_has_profile_condition_label($settings, $argument_labels) { + return t('@user has his @type created', $argument_labels + array('@type' => node_get_types('name', $settings['type']))); +} + +/** + * Implementation of hook_rules_action_info(). + */ +function content_profile_rules_action_info() { + return array( + 'content_profile_action_load' => array( + 'label' => t('Load Content Profile'), + 'arguments' => array( + 'user' => array('type' => 'user', 'label' => t('User, whose profile should be loaded')), + ), + 'new variables' => array( + 'profile_node' => array('type' => 'node', 'label' => t('Content Profile')), + ), + 'module' => 'Content Profile', + ), + ); +} + +/** + * Loads a Content Profile + */ +function content_profile_action_load($user, $settings) { + if ($node = content_profile_load($settings['type'], $user->uid)) { + return array('profile_node' => $node); + } +} + +function content_profile_action_load_form($settings, &$form) { + $settings += array('type' => array()); + $form['settings']['type'] = array( + '#type' => 'select', + '#title' => t('Content Profile Content Type'), + '#options' => content_profile_get_types('names'), + '#default_value' => $settings['type'], + '#description' => t('Select the Content Profile content type to load.'), + '#required' => TRUE, + ); +} + +function content_profile_action_load_label($settings, $argument_labels) { + return t("Load @user's @type", $argument_labels + array('@type' => node_get_types('name', $settings['type']))); +} + + +/** + * Support upgrading from nodeprofile-workflow-ng integration. + */ +function nodeprofile_user_has_profile_condition_upgrade(&$element) { + $element['#name'] = 'content_profile_user_has_profile_condition'; +} +function nodeprofile_action_load_upgrade(&$element) { + $element['#name'] = 'content_profile_action_load'; +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.rules_defaults.inc b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.rules_defaults.inc new file mode 100644 index 0000000000000000000000000000000000000000..b623755bd258db51f66eaefbed3f405cb55df33f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.rules_defaults.inc @@ -0,0 +1,111 @@ +<?php +// $Id: content_profile.rules_defaults.inc,v 1.1.2.2 2009/01/26 15:33:00 fago Exp $ +/** + * @file Rules default rules + */ + +/** + * Implementation of hook_rules_defaults(). + * Add a disabled default rule which redirects to the profile creation page, if users have + * no profile. + */ +function content_profile_rules_defaults() { + $type = array_shift(array_keys(content_profile_get_types('names'))); + $config = +array ( + 'rules' => + array ( + 'content_profile_rule_1' => + array ( + '#type' => 'rule', + '#set' => 'event_user_login', + '#label' => 'Redirect to profile creation page, if users have no profile.', + '#active' => 0, + '#weight' => '0', + '#conditions' => + array ( + 0 => + array ( + '#negate' => 1, + '#weight' => 0, + '#info' => + array ( + 'label' => 'Logged in user has his Profile created', + 'arguments' => + array ( + 'user' => + array ( + 'type' => 'user', + 'label' => 'User', + ), + ), + 'module' => 'Content Profile', + ), + '#name' => 'content_profile_user_has_profile_condition', + '#settings' => + array ( + 'type' => $type, + '#argument map' => + array ( + 'account' => 'user', + ), + ), + '#type' => 'condition', + ), + ), + '#actions' => + array ( + 0 => + array ( + '#type' => 'action', + '#settings' => + array ( + 'path' => 'node/add/'. str_replace('_', '-', $type), + 'query' => '', + 'fragment' => '', + 'force' => 1, + 'override' => 1, + ), + '#name' => 'rules_action_drupal_goto', + '#info' => + array ( + 'label' => 'Redirect to profile creation page', + 'label callback' => false, + 'module' => 'System', + 'eval input' => + array ( + 0 => 'path', + 1 => 'query', + 2 => 'fragment', + ), + ), + '#weight' => 0, + ), + 1 => + array ( + '#weight' => 0, + '#info' => + array ( + 'label' => 'Show a message', + 'label callback' => false, + 'module' => 'System', + 'eval input' => + array ( + 0 => 'message', + ), + ), + '#name' => 'rules_action_drupal_message', + '#settings' => + array ( + 'message' => 'You haven\'t filled out your profile information yet. Please do so now!', + 'error' => 1, + ), + '#type' => 'action', + ), + ), + ), + ), +); + + return $config; +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.theme.inc b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..ab9b2e00e0771302c927cfdada23100349cd4c1a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.theme.inc @@ -0,0 +1,113 @@ +<?php +// $Id: content_profile.theme.inc,v 1.1.2.9 2009/09/15 15:35:47 fago Exp $ + +/** + * @file + * Theme and template preprocessing code + */ + +/** + * Themes the add link. + */ +function theme_content_profile_display_add_link($element) { + $type = $element['#content_type']; + $uid = $element['#admin'] ? 'uid='. intval($element['#uid']) .'&' : ''; + $text = t($element['#admin'] ? "Create the user's @profile_node." : "Create your @profile_node.", array('@profile_node' => node_get_types('name', $type))); + return l($text, content_profile_get_add_path($type, $element['#uid']), array('query' => $uid . drupal_get_destination(), 'html' => TRUE)); +} + +/** + * Theme function for the content_profile display as link + */ +function theme_content_profile_display_link($element) { + if ($node = content_profile_load($element['#content_type'], $element['#uid'])) { + if (node_access('view', $node)) { + $output = l(node_get_types('name', $node->type), 'node/'. $node->nid); + if ($element['#edit_link'] && node_access('update', $node)) { + $output .= ' '. l('['. t('edit') .']', content_profile_get_edit_path($node), array('query' => drupal_get_destination())); + } + return $output; + } + } +} + +/** + * Implementation of content_profile_preprocess_HOOK() + */ +function content_profile_preprocess_content_profile_display_view(&$variables) { + $element = $variables['element']; + $node = content_profile_load($element['#content_type'], $element['#uid']); + $variables['node'] = &$node; + $variables['uid'] = $element['#uid']; + $variables['type'] = $element['#content_type']; + + $path = drupal_get_path('module', 'content_profile') .'/content_profile.css'; + drupal_add_css($path, 'module', 'all', FALSE); + + $variables['title'] = check_plain(node_get_types('name', $node->type)); + + $tabs = array(); + if ($element['#edit_link']) { + $tabs[] = theme('content_profile_display_tab_view', $node); + $tabs[] = theme('content_profile_display_tab_edit', $node); + } + if (count($tabs) > 0) { + $variables['tabs'] = $tabs; + } + $variables['content'] = node_view($node, ($element['#style'] == 'teaser'), TRUE, TRUE); +} + +/** + * Themes the view tab + */ +function theme_content_profile_display_tab_view($node) { + return l(t('View'), 'node/'. $node->nid); +} + +/** + * Themes the edit tab + */ +function theme_content_profile_display_tab_edit($node) { + if (node_access('update', $node)) { + return l(t('Edit'), content_profile_get_edit_path($node), array('query' => drupal_get_destination())); + } +} + +/** + * Gets the edit path for a content_profile + */ +function content_profile_get_edit_path($node) { + $handler = variable_get('content_profile_path_handler', 'content_profile_default_path_handler'); + return $handler('edit', $node, $node->uid); +} + +/** + * Gets the add path for a content_profile of the active user + */ +function content_profile_get_add_path($type, $uid) { + $handler = variable_get('content_profile_path_handler', 'content_profile_default_path_handler'); + return $handler('add', $type, $uid); +} + +/** + * Default path handler for content profile, which uses the default system paths + * + * @param $action 'add' or 'edit + * @param $arg For 'add' the content type, for 'edit' the node to be edited + * @param $uid the uid of the profile's owner. + */ +function content_profile_default_path_handler($action, $arg, $uid) { + $type = $action == 'add' ? $arg : $arg->type; + if (content_profile_get_settings($type, 'edit_tab') == 'top') { + return 'user/'. $uid . '/profile/'. $type; + } + elseif (content_profile_get_settings($type, 'edit_tab') == 'sub') { + return 'user/'. $uid . '/edit/'. $type; + } + elseif ($action == 'add') { + return 'node/add/'. str_replace('_', '-', $arg); + } + else { + return 'node/'. $arg->nid .'/edit'; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.theme_vars.inc b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.theme_vars.inc new file mode 100644 index 0000000000000000000000000000000000000000..38511b16b56fb99dd95f4f274bb03ded69059a77 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/content_profile.theme_vars.inc @@ -0,0 +1,119 @@ +<?php +// $Id: content_profile.theme_vars.inc,v 1.1.2.6 2009/07/31 16:41:15 fago Exp $ + +/** + * @file + * Provides a helper class for lazy loading of variables for themes. + */ + +/** + * A helper class, which offers lazy loading of variables for themes. + */ +class content_profile_theme_variables { + + var $uid; + var $_cache = array(); + + function content_profile_theme_variables($uid) { + $this->uid = $uid; + } + + /** + * Gets the user id of the profiles owner. + */ + function get_uid() { + return $uid; + } + + /** + * Gets all type names keyed with their machine readable names. + */ + function get_profile_types() { + return content_profile_get_types('names'); + } + + /** + * Gets all template variables for the content profile of this type. + * + * @param $type + * The type of the user's content profile + * @param $teaser + * Whether the value is to be generated for the teaser. + * @param $page + * Whether the value is to be generated for the page view. + * + * @return + * An array of variables available for the profile node + * or FALSE if there has been no profile created yet. + */ + function get_variables($type, $teaser = FALSE, $page = FALSE) { + if (!isset($this->_cache[$type][$teaser][$page])) { + $this->_cache[$type][$teaser][$page] = FALSE; + + if ($node = content_profile_load($type, $this->uid)) { + // Make sure the node is prepared for viewing + $node = node_build_content($node, $teaser, $page); + $vars = array('node' => $node, 'teaser' => $teaser, 'page' => $page); + + // Apply all node template preprocessors + foreach ($this->_get_node_preprocessors() as $function) { + if (function_exists($function)) { + $function($vars, 'node'); + } + } + $this->_cache[$type][$teaser][$page] = $vars; + } + } + return $this->_cache[$type][$teaser][$page]; + } + + /** + * Gets a single template variable for the content profile of this type. + * + * @param $type + * The type of the user's content profile + * @param $name + * The name of the variable to get. + * + * @return + * The variable or FALSE if there has been no profile created yet. + */ + function get_variable($type, $name) { + if ($vars = $this->get_variables($type)) { + return $vars[$name]; + } + return FALSE; + } + + + /** + * Generate a display of the given node. + * + * @param $type + * The type of the user's content profile + * @param $teaser + * Whether to display the teaser only or the full form. + * @param $page + * Whether the node is being displayed by itself as a page. + * @param $links + * Whether or not to display node links. Links are omitted for node previews. + * + * @return + * An HTML representation of the themed node or FALSE if there has been no profile created yet. + */ + function get_view($type, $teaser = FALSE, $page = FALSE, $links = TRUE) { + if ($node = content_profile_load($type, $this->uid)) { + return node_view($node, $teaser, $page, $links); + } + return FALSE; + } + + + function _get_node_preprocessors() { + $hooks = theme_get_registry(); + $functions = $hooks['node']['preprocess functions']; + // We don't need 'template_preprocess' + unset($functions[0]); + return $functions; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.info b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.info new file mode 100644 index 0000000000000000000000000000000000000000..95a0ba7db9443dadceb998cf39d1d42bf8716113 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.info @@ -0,0 +1,12 @@ +; $Id: content_profile_registration.info,v 1.1.2.4 2009/04/21 13:59:38 fago Exp $ +name = "Content Profile User Registration" +description = "Enable content profile features during user registration" +package = "Content Profile" +core = 6.x +dependencies[] = content_profile +; Information added by drupal.org packaging script on 2010-04-07 +version = "6.x-1.0" +core = "6.x" +project = "content_profile" +datestamp = "1270662007" + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.install b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.install new file mode 100644 index 0000000000000000000000000000000000000000..2ca379e694ec29117379f050b28162c7f083f6b1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.install @@ -0,0 +1,23 @@ +<?php +// $Id: content_profile_registration.install,v 1.1.2.1 2009/05/31 11:56:50 fago Exp $ + +/** + * @file Content Profile Registration - Installation file. + */ + +/** + * Implementation of hook_install(). + */ +function content_profile_registration_install() { + // Set the weight to 1, so we are the last one altering the form. + db_query("UPDATE {system} SET weight = 1 WHERE name = 'content_profile_registration'"); +} + +/** + * Update the modules weight to 1. + */ +function content_profile_registration_update_6001() { + $ret = array(); + $ret[] = update_sql("UPDATE {system} SET weight = 1 WHERE name = 'content_profile_registration'"); + return $ret; +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.module b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.module new file mode 100644 index 0000000000000000000000000000000000000000..537f6d7cc1505a8759995c7e67a1ab2e72a0da68 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_registration.module @@ -0,0 +1,277 @@ +<?php +// $Id: content_profile_registration.module,v 1.1.2.36 2010/03/26 16:32:28 fago Exp $ + +/** + * @file + * Allows exposure and processing of content_profile node fields at user registration + */ + +/** + * Implementation of hook_form_alter(). + */ +function content_profile_registration_form_alter(&$form, &$form_state, $form_id) { + if ($form_id == 'user_register') { + require_once drupal_get_path('module', 'node') .'/node.pages.inc'; + + // Allow other modules to customize the used profile types, so modules + // can easily customize the registration form. + $default_types = content_profile_get_types('names', (arg(0) == 'admin' ? 'admin_user_create_use' : 'registration_use')); + $form += array('#content_profile_registration_use_types' => $default_types); + + foreach ($form['#content_profile_registration_use_types'] as $type => $typename) { + content_profile_registration_add_profile_form($type, $form, $form_state); + } + } + elseif ($form_id == 'content_profile_admin_settings') { + $type = $form_state['type']; + // Let other modules add registration child elements before us! + $form += array('registration' => array()); + $form['registration'] += array( + '#type' => 'fieldset', + '#title' => t('User Registration'), + '#description' => t('Customize how this content profile shows up on the user registration page.'), + '#collapsible' => TRUE, + ); + $form['registration']['registration_use'] = array( + '#type' => 'checkbox', + '#title' => t('Use on Registration'), + '#description' => t('Use this content type on the user registration page'), + '#default_value' => content_profile_get_settings($type, 'registration_use'), + ); + $form['registration']['admin_user_create_use'] = array( + '#type' => 'checkbox', + '#title' => t('Use on administrative user creation form'), + '#description' => t('Use this content type when an administrative user creates a new user'), + '#default_value' => content_profile_get_settings($type, 'admin_user_create_use'), + ); + $form['registration']['registration_hide'] = array( + '#type' => 'checkboxes', + '#title' => t('Hide form fields'), + '#description' => t('Hide fields from the user registration form. Required fields cannot be hidden and are not shown here.'), + '#options' => _content_profile_registration_get_field_select($type), + '#default_value' => content_profile_get_settings($type, 'registration_hide'), + ); + array_unshift($form['#submit'], 'content_profile_registration_admin_form_submit'); + } +} + +function content_profile_registration_admin_form_submit($form, &$form_state) { + $form_state['values']['registration_hide'] = array_keys(array_filter($form_state['values']['registration_hide'])); +} + +/** + * Helper function to return all available fields for a particular content type. + * + * @param string $type + * The content type to return fields for. + * @return array + * Associated fields for the given content type. + */ +function _content_profile_registration_get_fields($type) { + $typeinfo = content_types($type); + return $typeinfo['fields']; +} + +/** + * Returns an array of selectable form elements that may be hidden, mostly containing CCK fields. + * + * @param string $type + * A content type to get the select elements for. + * @return Array + * An array of fields suitable for use in a select field. +*/ +function _content_profile_registration_get_field_select($type) { + $fields = module_exists('content') ? _content_profile_registration_get_fields($type) : array(); + $return = array(); + if (!module_exists('auto_nodetitle') || auto_nodetitle_get_setting($type) != AUTO_NODETITLE_ENABLED) { + $return['title'] = t('Title'); + } + foreach ($fields as $fieldname => $info) { + if (!$info['required']) { + $return[$fieldname] = drupal_ucfirst($info['widget']['label']); + } + } + $return['other'] = t('Other form elements (except for required CCK fields)'); + + return $return; +} + +/** + * Adds in the profile form of the given content type to the registration form + * + * @see content_profile_registration_alter_weights() + * @see content_profile_registration_user_register_validate() + * @see content_profile_registration_user_register_submit() + */ +function content_profile_registration_add_profile_form($type, &$form, &$form_state) { + // Initialize new node and add in its form. + $node = array('uid' => 0, 'name' => '', 'type' => $type); + // Get the original node form. + $node_form = drupal_retrieve_form($type .'_node_form', $form_state, $node); + drupal_prepare_form($type .'_node_form', $node_form, $form_state); + + $node_form += array('#field_info' => array()); + $form_add = array(); + + // If non-CCK form elements are hidden, only copy over the CCK stuff + if (in_array('other', content_profile_get_settings($type, 'registration_hide'))) { + foreach ($node_form['#field_info'] as $field_name => $info) { + if (isset($node_form[$field_name])) { + $form_add[$field_name] = $node_form[$field_name]; + } + } + // Copy over any fieldgroups + $keys = array_keys($node_form); + foreach ($keys as $key) { + if (stristr($key, 'group_')) { + $form_add[$key] = $node_form[$key]; + } + } + // Add the title + $form_add['title'] = $node_form['title']; + + // Set this to the values of one node, as it might be need by some #ahah callbacks + $form_add['#node'] = $node_form['#node']; + $form_add['type'] = $node_form['type']; + } + else { + foreach (array('uid', 'name', 'author', 'buttons', 'language', '#theme', 'options') as $key) { + unset($node_form[$key]); + } + $form_add = $node_form; + } + + // Hide fields as configured + foreach (content_profile_get_settings($type, 'registration_hide') as $field_name) { + if (module_exists('fieldgroup') && ($group_name = _fieldgroup_field_get_group($type, $field_name))) { + unset($form_add[$group_name][$field_name]); + if (count(element_children($form_add[$group_name])) == 0) { + unset($form_add[$group_name]); + } + } + else { + unset($form_add[$field_name]); + } + } + + // Add in the new form elements into $form. + $form += array('#field_info' => array()); + $form['#field_info'] += $node_form['#field_info']; + $form += $form_add; + + // Add in further callbacks needed, if not yet done. + if (!isset($form['#content_profile_weights'])) { + $form['#submit'][] = 'content_profile_registration_user_register_submit'; + $form['#validate'][] = 'content_profile_registration_user_register_validate'; + $form['#pre_render'][] = 'content_profile_registration_alter_weights'; + } + + // Care for the weights: Make use of the content types weight and sort the fields in behalf + // The weights will be applied by the pre_render callback. + $form += array('#content_profile_weights' => array()); + $weight = content_profile_get_settings($type, 'weight') + 1; + foreach (element_children($form_add) as $key) { + $form['#content_profile_weights'] += array($key => $weight); + } + + // Set the enctype, if necessary. + if (isset($node_form['#attributes']['enctype'])){ + $form['#attributes']['enctype'] = $node_form['#attributes']['enctype']; + } +} + +/** + * Pre render callback that makes sure our elements are grouped together. + * The ordering in between the single elements is kept. + * + * @see content_profile_registration_add_profile_form(). + */ +function content_profile_registration_alter_weights($elements) { + foreach ($elements['#content_profile_weights'] as $key => $weight) { + if (isset($elements[$key]) && is_array($elements[$key])) { + $elements[$key] += array('#weight' => 0); + $elements[$key]['#weight'] = $weight + $elements[$key]['#weight'] / 1000; + } + } + return $elements; +} + + +/** + * Validates the user registration form + */ +function content_profile_registration_user_register_validate($form, &$form_state) { + require_once drupal_get_path('module', 'node') .'/node.pages.inc'; + + foreach ($form['#content_profile_registration_use_types'] as $type => $typename) { + $node = (object)$form_state['values']; + $node->type = $type; + node_object_prepare($node); + + // Make sure there is no user name so we can node_validate + unset($node->name); + + if (!in_array('other', content_profile_get_settings($type, 'registration_hide'))) { + node_validate($node, $form); + } + elseif (module_exists('content')) { + content_validate($node); + } + + $form_state['content_profile_registration'][$type]['node'] = $node; + } + // Remove our added values + foreach ($form['#content_profile_weights'] as $key => $weight) { + _content_profile_registration_remove_values($key, $form[$key], $form_state); + } +} + +/** + * Recursivly removes all form values created by this element or its children. + */ +function _content_profile_registration_remove_values($key, $element, &$form_state) { + if ((isset($element['#input']) || !empty($element['#tree'])) && isset($form_state['values'][$key])) { + unset($form_state['values'][$key]); + } + elseif (empty($element['#input']) && empty($element['#tree'])) { + foreach (element_children($element) as $key) { + _content_profile_registration_remove_values($key, $element[$key], $form_state); + } + } +} + + +/** + * Submits the user registration form + */ +function content_profile_registration_user_register_submit($form, &$form_state) { + foreach ($form['#content_profile_registration_use_types'] as $type => $typename) { + if ($node = &$form_state['content_profile_registration'][$type]['node']) { + // Set user's information for the node. + if (empty($node->title) && (!module_exists('auto_nodetitle') || auto_nodetitle_get_setting($type) != AUTO_NODETITLE_OPTIONAL)) { + $node->title = $form_state['user']->name; + } + $node->uid = $form_state['user']->uid; + $node->name = $form_state['user']->name; + + // Create the node. + $node = node_submit($node); + node_save($node); + // Give us a nice log message. + if ($node->nid) { + watchdog('content', 'Content Profile: added %user %type upon registration.', array('%user' => $node->name, '%type' => $type), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid")); + } + } + } +} + +/** + * Implementation of hook_content_profile_settings(). + */ +function content_profile_registration_content_profile_settings() { + return array( + 'registration_use' => FALSE, + 'admin_user_create_use' => FALSE, + 'registration_hide' => array(), + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_tokens.info b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_tokens.info new file mode 100644 index 0000000000000000000000000000000000000000..61b049e8b7a386059fe3a02dd0e6ddb6910cbd3c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_tokens.info @@ -0,0 +1,15 @@ +; $Id: content_profile_tokens.info,v 1.1.2.1 2009/11/03 14:20:17 fago Exp $ +name = Content Profile Tokens +description = Add user tokens for content profiles. +package = "Content Profile" +dependencies[] = content_profile +dependencies[] = token +dependencies[] = content +core = 6.x + +; Information added by drupal.org packaging script on 2010-04-07 +version = "6.x-1.0" +core = "6.x" +project = "content_profile" +datestamp = "1270662007" + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_tokens.module b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_tokens.module new file mode 100644 index 0000000000000000000000000000000000000000..47fb0f3a4bc80943c41f0b0d5fd53bda294b291e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/modules/content_profile_tokens.module @@ -0,0 +1,94 @@ +<?php +// $Id: content_profile_tokens.module,v 1.1.2.1 2009/11/03 14:20:17 fago Exp $ + +/** + * @file + * Implementations of token module hooks for the content profile module. + * + * @ingroup token + */ + +/** + * Implementation of hook_token_values(). + */ +function content_profile_tokens_token_values($type, $object = NULL, $options = array()) { + $values = array(); + $types = content_profile_get_types('types'); + switch ($type) { + case 'user': + foreach($types as $type_name => $type) { + if (isset($object)) { + $profile = content_profile_load($type_name, $object->uid); + } + else { + global $user; + $profile = content_profile_load($type_name, $user->uid); + } + $fields = content_types($type_name); + foreach ($fields['fields'] as $field_name => $field) { + if (!$field['multiple'] && ($field['widget']['type'] == 'text_textfield' || $field['widget']['type'] == 'number')) { + $values['content-profile-'. $type_name .'-'. substr($field_name, 6)] = check_plain($profile->{$field_name}[0]['value']); + $values['content-profile-'. $type_name .'-'. substr($field_name, 6) .'-raw'] = $profile->{$field_name}[0]['value']; + } + } + } + break; + + case 'flag_friend': + if(!empty($object)) { + foreach($types as $type_name => $type) { + $profile_requestor = content_profile_load($type_name, $object->friend->uid); + $profile_requestee = content_profile_load($type_name, $object->uid); + + $fields = content_types($type_name); + foreach ($fields['fields'] as $field_name => $field) { + if (!$field['multiple'] && ($field['widget']['type'] == 'text_textfield' || $field['widget']['type'] == 'number')) { + $values['requestor-'. $type_name .'-'. substr($field_name, 6)] = check_plain($profile_requestor->{$field_name}[0]['value']); + $values['requestor-'. $type_name .'-'. substr($field_name, 6) .'-raw'] = $profile_requestor->{$field_name}[0]['value']; + + $values['requestee-'. $type_name .'-'. substr($field_name, 6)] = check_plain($profile_requestee->{$field_name}[0]['value']); + $values['requestee-'. $type_name .'-'. substr($field_name, 6) .'-raw'] = $profile_requestee->{$field_name}[0]['value']; + } + } + } + } + break; + } + return $values; +} + +/** + * Implementation of hook_token_list(). + */ +function content_profile_tokens_token_list($type = 'all') { + $tokens = array(); + if ($type == 'user' || $type == 'all') { + $types = content_profile_get_types('types'); + foreach ($types as $type_name => $type) { + + $fields = content_types($type_name); + foreach ($fields['fields'] as $field_name => $field) { + if (!$field['multiple'] && ($field['widget']['type'] == 'text_textfield' || $field['widget']['type'] == 'number')) { + $tokens['user']['content-profile-'. $type_name .'-'. substr($field_name, 6)] = t($fields['description']) .'-'. t($field['widget']['label']); + $tokens['user']['content-profile-'. $type_name .'-'. substr($field_name, 6) .'-raw'] = t($fields['description']) .'-'. t($field['widget']['label']) .' '. t('WARNING - raw user input'); + } + } + } + } + + if ($type == 'flag_friend' && module_exists('flag_friend')) { + foreach($types as $type_name => $type) { + $fields = content_types($type_name); + foreach ($fields['fields'] as $field_name => $field) { + if (!$field['multiple'] && ($field['widget']['type'] == 'text_textfield' || $field['widget']['type'] == 'number')) { + $tokens['content_profile_flag_friend']['requestor-'. $type_name .'-'. substr($field_name, 6)] = t('Requestor:') . t($fields['description']) .'-'. t($field['widget']['label']); + $tokens['content_profile_flag_friend']['requestor-'. $type_name .'-'. substr($field_name, 6) .'-raw'] = t('Requestor:') . t($fields['description']) .'-'. t($field['widget']['label']) .' '. t('WARNING - raw user input'); + + $tokens['content_profile_flag_friend']['requestee-'. $type_name .'-'. substr($field_name, 6)] = t('Requestee:') . t($fields['description']) .'-'. t($field['widget']['label']); + $tokens['content_profile_flag_friend']['requestee-'. $type_name .'-'. substr($field_name, 6) .'-raw'] = t('Requestee:') .t($fields['description']) .'-'. t($field['widget']['label']) .' '. t('WARNING - raw user input'); + } + } + } + } + return $tokens; +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/panels/relationships/node_from_user.inc b/drupal/sites/default/boinc/modules/contrib/content_profile/panels/relationships/node_from_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..e6f16180c2337302a88c82a17beaa76513091873 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/panels/relationships/node_from_user.inc @@ -0,0 +1,67 @@ +<?php +// $Id: node_from_user.inc,v 1.1.2.2 2009/08/05 13:41:06 fago Exp $ + +/** + * @file + * Provides a CTools (Panels) relationship that gets a node context from the + * user context based on nodes marked as content profiles. + */ + +/** + * Implementation of specially named hook_ctools_relationships(). + */ +function content_profile_node_from_user_ctools_relationships() { + $args['node_from_user'] = array( + 'title' => t("Profile Node"), + 'keyword' => 'content_profile', + 'description' => t('Adds a Content Profile from user context'), + 'required context' => new ctools_context_required(t('User'), 'user'), + 'context' => 'content_profile_node_from_user_ctools_context', + 'settings form' => 'content_profile_node_from_user_ctools_settings_form', + 'settings form validate' => 'content_profile_node_from_user_ctools_settings_form_validate', + ); + + return $args; +} + +/** + * Return a new context based on an existing context. + */ +function content_profile_node_from_user_ctools_context($context, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data) || !isset($context->data->uid)) { + $new_context = ctools_context_create_empty('node', NULL); + } + else { + // Load the node for the requested type + $uid = $context->data->uid; + $content_profile_node = content_profile_load($conf['type'], $uid); + + // Send it to ctools. + $new_context = ctools_context_create('node', $content_profile_node); + } + + // Have content profile relationships limit CCK field availability. + if (isset($new_context->restrictions['type'])) { + $new_context->restrictions['type'][] = $conf['type']; + } + else { + $new_context->restrictions['type'] = array($conf['type']); + } + return $new_context; +} + +/** + * Settings form for the relationship + */ +function content_profile_node_from_user_ctools_settings_form($conf) { + $options = content_profile_get_types('names'); + $form['type'] = array( + '#type' => 'select', + '#title' => t('Relationship type'), + '#options' => $options, + '#default_value' => $conf['type'] + ); + + return $form; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/tests/content_profile.test b/drupal/sites/default/boinc/modules/contrib/content_profile/tests/content_profile.test new file mode 100644 index 0000000000000000000000000000000000000000..38d90fc7d51b6fa288de4c09fc41874b410e992b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/tests/content_profile.test @@ -0,0 +1,55 @@ +<?php +// $Id: content_profile.test,v 1.1.2.2 2008/07/24 09:57:57 fago Exp $ + +/** + * @file + * Some basic tests for content profile. + */ + +class ContentProfileTest extends DrupalTestCase { + function get_info() { + return array( + 'name' => 'One content profile per user', + 'desc' => t('Assure that only one content profile per user is allowed.'), + 'group' => 'Content Profile', + ); + } + + function testOneProfilePerUser() { + // create a content_profile node + $user1 = $this->drupalCreateUserRolePerm(array('administer content types')); + $this->drupalLoginUser($user1); + + $content_profile_name = $this->randomName(); + $content_profile_type = strtolower($this->randomName()); + + $edit = array( + 'name' => $content_profile_name, + 'type' => $content_profile_type, + 'content_profile' => 'Array', + ); + $this->drupalPost('admin/content/types/add', $edit, t('Save content type')); + $this->assertText('The content type '. $content_profile_name .' has been added.'); + $this->clickLink(t('Log out')); + + // create new user who is allowed to create a content_profile node + $user2 = $this->drupalCreateUserRolePerm(array('create '. $content_profile_type .' content', 'edit own '. $content_profile_type .' content')); + $this->drupalLoginUser($user2); + + // create a content_profile node + $edit = array( + 'title' => $this->randomName(), + 'body' => $this->randomName(), + ); + $this->drupalPost('node/add/'. str_replace('_', '-', $content_profile_type), $edit, t('Save')); + + $this->assertText($content_profile_name .' '. $edit['title'] .' has been created.'); + + // test if the user can create another content_profile node + $url = url('node/add/'. str_replace('_', '-', $content_profile_type), array('absolute' => TRUE)); + $this->get($url); + $this->assertResponse(200); + $this->assertText('Edit'); + $this->assertText($edit['title']); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/translations/content_profile.pot b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/content_profile.pot new file mode 100644 index 0000000000000000000000000000000000000000..d3c8e41a00c8b80569ed0825065787860fc3d3ff --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/content_profile.pot @@ -0,0 +1,265 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# content_profile.rules.inc,v 1.1.2.2 2009/03/30 10:20:01 fago +# node_from_user.inc,v 1.1.2.1 2009/06/15 10:55:24 fago +# content_profile.module,v 1.1.2.39 2009/06/15 10:55:24 fago +# content_profile.info,v 1.1.2.1 2008/02/01 16:00:24 fago +# content_profile_registration.info,v 1.1.2.4 2009/04/21 13:59:38 fago +# content_profile.views.inc,v 1.1.2.1 2008/09/26 16:09:43 fago +# content_profile.theme.inc,v 1.1.2.8 2009/01/07 10:58:05 fago +# content_profile_registration.module,v 1.1.2.32 2009/05/31 11:56:50 fago +# content_profile.install,v 1.1.2.7 2009/01/09 15:55:07 fago +# content_profile_views_handler_relationship.inc,v 1.1.2.3 2009/06/11 15:14:21 fago +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-10-22 00:41+0200\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: content_profile.rules.inc:15 +msgid "User has content profile" +msgstr "" + +#: content_profile.rules.inc:17 panels/relationships/node_from_user.inc:18 +msgid "User" +msgstr "" + +#: content_profile.rules.inc:33;76 +msgid "Content Profile Content Type" +msgstr "" + +#: content_profile.rules.inc:36 +msgid "Select the Content Profile content type to check for." +msgstr "" + +#: content_profile.rules.inc:42 +msgid "@user has his @type created" +msgstr "" + +#: content_profile.rules.inc:51 +msgid "Load Content Profile" +msgstr "" + +#: content_profile.rules.inc:53 +msgid "User, whose profile should be loaded" +msgstr "" + +#: content_profile.rules.inc:56 content_profile.module:260 content_profile.info:0;0 modules/content_profile_registration.info:0 views/content_profile.views.inc:16;22 +msgid "Content Profile" +msgstr "" + +#: content_profile.rules.inc:79 +msgid "Select the Content Profile content type to load." +msgstr "" + +#: content_profile.rules.inc:85 +msgid "Load @user's @type" +msgstr "" + +#: content_profile.theme.inc:27 +msgid "edit" +msgstr "" + +#: content_profile.theme.inc:64 +msgid "View" +msgstr "" + +#: content_profile.theme.inc:72 content_profile.module:35 +msgid "Edit" +msgstr "" + +#: content_profile.module:130 +msgid "Weight" +msgstr "" + +#: content_profile.module:132 +msgid "The weight of content of this content type where ever they appear - this applies to the input form integration as well to the display integration." +msgstr "" + +#: content_profile.module:137 +msgid "Display settings" +msgstr "" + +#: content_profile.module:138 +msgid "Customize the display of this content profile." +msgstr "" + +#: content_profile.module:143 +msgid "User page display style" +msgstr "" + +#: content_profile.module:146 +msgid "Don't display this content profile on the user account page" +msgstr "" + +#: content_profile.module:147 +msgid "Display it as link to the profile content" +msgstr "" + +#: content_profile.module:148 +msgid "Display the full content" +msgstr "" + +#: content_profile.module:149 +msgid "Display the content's teaser" +msgstr "" + +#: content_profile.module:154 +msgid "Include an edit link to the display" +msgstr "" + +#: content_profile.module:159 +msgid "Show a link to the content profile creation page, if there is no profile." +msgstr "" + +#: content_profile.module:161 +msgid "If selected and the user has no profile of this type yet, a link to add one is shown on the user page." +msgstr "" + +#: content_profile.module:165 +msgid "Profile edit tab" +msgstr "" + +#: content_profile.module:168 +msgid "None" +msgstr "" + +#: content_profile.module:169 +msgid "Show a tab at the user's page" +msgstr "" + +#: content_profile.module:170 +msgid "Show a secondary tab below the user's edit tab" +msgstr "" + +#: content_profile.module:175 +msgid "Submit" +msgstr "" + +#: content_profile.module:267 +msgid "Use this content type as a content profile for users" +msgstr "" + +#: content_profile.module:368 +msgid "@type %title has been deleted." +msgstr "" + +#: content_profile.module:393 +msgid "This user already has a content profile of this type. You can only create one profile per user." +msgstr "" + +#: content_profile.module:367 modules/content_profile_registration.module:254 +msgid "content" +msgstr "" + +#: content_profile.module:367 +msgid "@type: deleted %title." +msgstr "" + +#: content_profile.module:39 +msgid "Content profile" +msgstr "" + +#: content_profile.module:40 +msgid "Configure the display and management of this content profile." +msgstr "" + +#: content_profile.install:34 +msgid "Profile" +msgstr "" + +#: content_profile.install:36 +msgid "A user profile built as content." +msgstr "" + +#: content_profile.info:0 +msgid "Use content types for user profiles." +msgstr "" + +#: modules/content_profile_registration.module:31 +msgid "User Registration" +msgstr "" + +#: modules/content_profile_registration.module:32 +msgid "Customize how this content profile shows up on the user registration page." +msgstr "" + +#: modules/content_profile_registration.module:37 +msgid "Use on Registration" +msgstr "" + +#: modules/content_profile_registration.module:38 +msgid "Use this content type on the user registration page" +msgstr "" + +#: modules/content_profile_registration.module:43 +msgid "Use on administrative user creation form" +msgstr "" + +#: modules/content_profile_registration.module:44 +msgid "Use this content type when an administrative user creates a new user" +msgstr "" + +#: modules/content_profile_registration.module:49 +msgid "Hide form fields" +msgstr "" + +#: modules/content_profile_registration.module:86 +msgid "Title" +msgstr "" + +#: modules/content_profile_registration.module:93 +msgid "Other form elements (except for required CCK fields)" +msgstr "" + +#: modules/content_profile_registration.module:254 +msgid "view" +msgstr "" + +#: modules/content_profile_registration.module:254 +msgid "Content Profile: added %user %type upon registration." +msgstr "" + +#: modules/content_profile_registration.info:0 +msgid "Content Profile User Registration" +msgstr "" + +#: modules/content_profile_registration.info:0 +msgid "Enable content profile features during user registration" +msgstr "" + +#: panels/relationships/node_from_user.inc:15 +msgid "Profile Node" +msgstr "" + +#: panels/relationships/node_from_user.inc:17 +msgid "Adds a Content Profile from user context" +msgstr "" + +#: panels/relationships/node_from_user.inc:56 +msgid "Relationship type" +msgstr "" + +#: views/content_profile.views.inc:15 +msgid "Node" +msgstr "" + +#: views/content_profile.views.inc:17 +msgid "Create a relationship to a content profile of the user." +msgstr "" + +#: views/content_profile_views_handler_relationship.inc:23 +msgid "Content type" +msgstr "" + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/translations/da.po b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/da.po new file mode 100644 index 0000000000000000000000000000000000000000..22d7dfc214b3b5a9bf9660d66651c78ce7330fdd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/da.po @@ -0,0 +1,271 @@ +# Dansk translation of content_profile (6.x-1.0-beta3) +# Copyright (c) 2009 by the Dansk translation team +# Generated from files: +# content_profile.theme.inc,v 1.1.2.8 2009/01/07 10:58:05 fago +# content_profile.module,v 1.1.2.32 2009/01/07 10:58:05 fago +# content_profile_registration.module,v 1.1.2.25 2009/01/07 11:02:28 fago +# content_profile.panels.inc,v 1.1.2.1 2009/01/04 12:02:19 fago +# content_profile.rules.inc,v 1.1.2.1 2009/01/07 11:36:36 fago +# content_profile.views.inc,v 1.1.2.1 2008/09/26 16:09:43 fago +# content_profile.install,v 1.1.2.6 2009/01/04 11:30:28 fago +# content_profile_views_handler_relationship.inc,v 1.1.2.2 2008/11/04 03:57:08 jgraham +# content_profile.info,v 1.1.2.1 2008/02/01 16:00:24 fago +# content_profile_registration.info,v 1.1.2.3 2008/07/24 10:16:40 fago +# +msgid "" +msgstr "" +"Project-Id-Version: content_profile (6.x-1.0-beta3)\n" +"POT-Creation-Date: 2009-05-29 12:14-0700\n" +"PO-Revision-Date: 2009-05-29 21:14+0100\n" +"Language-Team: Dansk <dansk@klid.dk>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"Last-Translator: Morten Wulff <wulff@ratatosk.net>\n" +"X-Poedit-Language: Danish\n" +"X-Poedit-Country: DENMARK\n" + +#: content_profile.theme.inc:27 +msgid "edit" +msgstr "redigér" + +#: content_profile.module:119 +msgid "Weight" +msgstr "Vægt" + +#: modules/content_profile_registration.module:161 +msgid "view" +msgstr "vis" + +#: content_profile.theme.inc:64 +msgid "View" +msgstr "Oversigt" + +#: content_profile.module:356; +#: modules/content_profile_registration.module:161 +msgid "content" +msgstr "indhold" + +#: content_profile.panels.inc:17; +#: content_profile.rules.inc:17 +msgid "User" +msgstr "Bruger" + +#: content_profile.theme.inc:72; +#: content_profile.module:30 +msgid "Edit" +msgstr "Redigér" + +#: content_profile.module:357 +msgid "@type %title has been deleted." +msgstr "@type %title slettet." + +#: content_profile.module:356 +msgid "@type: deleted %title." +msgstr "@type: %title slettet." + +#: views/content_profile.views.inc:15 +msgid "Node" +msgstr "Indholdselement" + +#: content_profile.install:34 +msgid "Profile" +msgstr "Profil" + +#: content_profile.module:164 +msgid "Submit" +msgstr "Indsend" + +#: content_profile.module:126 +msgid "Display settings" +msgstr "Indstillinger for visning" + +#: views/content_profile_views_handler_relationship.inc:23 +msgid "Content type" +msgstr "Indholdstype" + +#: content_profile.module:157 +msgid "None" +msgstr "Ingen" + +#: content_profile.panels.inc:54 +msgid "Relationship type" +msgstr "Forbindelsestype" + +#: content_profile.panels.inc:14 +msgid "Profile Node from user" +msgstr "Profil-indholdselement fra bruger" + +#: content_profile.panels.inc:16 +msgid "Adds a Content Profile from user context" +msgstr "Tilbføjer en Content Profile fra brugerkontekst" + +#: content_profile.rules.inc:15 +msgid "User has content_profile" +msgstr "Bruger har content_profile" + +#: content_profile.rules.inc:33,76 +msgid "Content Profile Content Type" +msgstr "Content Profile indholdstype" + +#: content_profile.rules.inc:36 +msgid "Select the Content Profile content type to check for." +msgstr "Vælg Content Profile indholdstypen der skal kigges efter." + +#: content_profile.rules.inc:42 +msgid "@user has his @type created" +msgstr "@user har oprettet sin @type" + +#: content_profile.rules.inc:51 +msgid "Load Content Profile" +msgstr "Indlæs Content Profile" + +#: content_profile.rules.inc:53 +msgid "User, whose profile should be loaded" +msgstr "Bruger hvis profil skal indlæses" + +#: content_profile.rules.inc:56; +#: content_profile.module:249; +#: content_profile.info:0; +#: modules/content_profile_registration.info:0; +#: views/content_profile.views.inc:16,22 +msgid "Content Profile" +msgstr "Content Profile" + +#: content_profile.rules.inc:79 +msgid "Select the Content Profile content type to load." +msgstr "Vælg Content Profile indholdstype som skal indlæses." + +#: content_profile.rules.inc:85 +msgid "Load @user's @type" +msgstr "Indlæs @users @type" + +#: content_profile.module:121 +msgid "The weight of content of this content type where ever they appear - this applies to the input form integration as well to the display integration." +msgstr "Vægten af denne indholdstype uanset hvor den optræder - det gælder både for integration i formularer og visning." + +#: content_profile.module:127 +msgid "Customize the display of this content profile." +msgstr "Tilpas visningen af denne Content Profile." + +#: content_profile.module:132 +msgid "User page display style" +msgstr "Brugerside udseende" + +#: content_profile.module:135 +msgid "Don't display this content profile on the user account page" +msgstr "Vis ikke denne Content Profile på profilsiden" + +#: content_profile.module:136 +msgid "Display it as link to the profile content" +msgstr "Vis den som et link til profilindholdet" + +#: content_profile.module:137 +msgid "Display the full content" +msgstr "Vis det fulde indhold" + +#: content_profile.module:138 +msgid "Display the content's teaser" +msgstr "Vis indholdets resumé" + +#: content_profile.module:143 +msgid "Include an edit link to the display" +msgstr "Inkludér et link til visningen" + +#: content_profile.module:148 +msgid "Show a link to the content profile creation page, if there is no profile." +msgstr "Vis et link til oprettelse af en Content Profile hvis der ikke er en profil." + +#: content_profile.module:150 +msgid "If selected and the user has no profile of this type yet, a link to add one is shown on the user page." +msgstr "Hvis brugeren endnu ikke har en profil af denne type, vises der et link til at oprette én på profilsiden." + +#: content_profile.module:154 +msgid "Profile edit tab" +msgstr "Profil redigeringsfane" + +#: content_profile.module:158 +msgid "Show a tab at the user's page" +msgstr "Vis en fane på brugerens profil" + +#: content_profile.module:159 +msgid "Show a secondary tab below the user's edit tab" +msgstr "Vis en sekundær fane under brugerens redigeringsfane" + +#: content_profile.module:256 +msgid "Use this content type as a content profile for users" +msgstr "Brug denne indholdstype som Content Profile for brugere" + +#: content_profile.module:377 +msgid "This user has already a content profile of this type. You can only create one profile per user." +msgstr "Denne bruger har allerede en Content Profile af denne type. Du kan kun oprette én profil pr. bruger." + +#: content_profile.module:34 +msgid "Content profile" +msgstr "Content Profile" + +#: content_profile.module:35 +msgid "Configure the display and management of this content profile." +msgstr "Konfigurér visning og håndtering af denne Content Profile." + +#: content_profile.module:0 +msgid "content_profile" +msgstr "content_profile" + +#: content_profile.install:36 +msgid "A user profile built as content." +msgstr "En brugerprofil bygget som indhold." + +#: content_profile.info:0 +msgid "Use content types for user profiles." +msgstr "Brug indholdstyper som brugerprofiler." + +#: modules/content_profile_registration.module:56 +msgid "User Registration" +msgstr "Brugeroprettelse" + +#: modules/content_profile_registration.module:57 +msgid "Customize how this content profile shows up on the user registration page." +msgstr "Tilpas hvordan denne Content Profile vises på brugeroprettelsessiden." + +#: modules/content_profile_registration.module:64 +msgid "Use on Registration" +msgstr "Brug ved oprettelse" + +#: modules/content_profile_registration.module:65 +msgid "Use this content type on the user registration page" +msgstr "Brug denne indholdstype på brugeroprettelsessiden" + +#: modules/content_profile_registration.module:72 +msgid "Hide these fields during registration" +msgstr "Skjul disse felter under brugeroprettelse" + +#: modules/content_profile_registration.module:79 +msgid "There are no fields defined, so registration integration is disabled." +msgstr "Der er ikke defineret nogen felter, så integration med brugeroprettelse er deaktiveret." + +#: modules/content_profile_registration.module:122 +msgid "Field Group: " +msgstr "Feltgruppe: " + +#: modules/content_profile_registration.module:161 +msgid "Content Profile: added %user %type upon registration." +msgstr "Content Profile: tilføjede %user %type ved oprettelse." + +#: modules/content_profile_registration.module:0 +msgid "content_profile_registration" +msgstr "content_profile_registration" + +#: modules/content_profile_registration.info:0 +msgid "Content Profile User Registration" +msgstr "Content Profile Brugeroprettelse" + +#: modules/content_profile_registration.info:0 +msgid "Enable content profile features during user registration" +msgstr "Aktivér Content Profile funktioner under brugeroprettelse" + +#: views/content_profile.views.inc:17 +msgid "Create a relationship to a content profile of the user." +msgstr "Opret en forbindelse til brugerens Content Profile." + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/translations/de.po b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/de.po new file mode 100644 index 0000000000000000000000000000000000000000..3e5f00bd969691b8c5d12a6fce52981a270a555b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/de.po @@ -0,0 +1,270 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (general) +# Copyright 2009 NAME <EMAIL@ADDRESS> +# Generated from files: +# content_profile.rules.inc,v 1.1.2.2 2009/03/30 10:20:01 fago +# node_from_user.inc,v 1.1.2.1 2009/06/15 10:55:24 fago +# content_profile.module,v 1.1.2.39 2009/06/15 10:55:24 fago +# content_profile.info,v 1.1.2.1 2008/02/01 16:00:24 fago +# content_profile_registration.info,v 1.1.2.4 2009/04/21 13:59:38 fago +# content_profile.views.inc,v 1.1.2.1 2008/09/26 16:09:43 fago +# content_profile.theme.inc,v 1.1.2.8 2009/01/07 10:58:05 fago +# content_profile_registration.module,v 1.1.2.32 2009/05/31 11:56:50 fago +# content_profile.install,v 1.1.2.7 2009/01/09 15:55:07 fago +# content_profile_views_handler_relationship.inc,v 1.1.2.3 2009/06/11 15:14:21 fago +# +msgid "" +msgstr "Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-10-22 00:41+0200\n" +"PO-Revision-Date: 2009-10-22 00:45+0100\n" +"Last-Translator: Thomas Zahreddin <thomas@voicehero.com>\n" +"Language-Team: German\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: content_profile.rules.inc:15 +msgid "User has content profile" +msgstr "Der Benutzer hat ein Profil." + +#: content_profile.rules.inc:17 +#: panels/relationships/node_from_user.inc:18 +msgid "User" +msgstr "Benutzer" + +#: content_profile.rules.inc:33;76 +msgid "Content Profile Content Type" +msgstr "Inhaltstyp Benutzerprofil" + +#: content_profile.rules.inc:36 +msgid "Select the Content Profile content type to check for." +msgstr "Wählen Sie einen Inhaltstyp zur Verwendung für das Benutzerprofil aus." + +#: content_profile.rules.inc:42 +msgid "@user has his @type created" +msgstr "@user hat @type erstellt" + +#: content_profile.rules.inc:51 +msgid "Load Content Profile" +msgstr "Benuterprofil laden" + +#: content_profile.rules.inc:53 +msgid "User, whose profile should be loaded" +msgstr "Benutzer, dessen Profil geladen werden soll" + +#: content_profile.rules.inc:56 +#: content_profile.module:260 +#: content_profile.info:0;0 +#: modules/content_profile_registration.info:0 +#: views/content_profile.views.inc:16;22 +msgid "Content Profile" +msgstr "Content Profile" + +#: content_profile.rules.inc:79 +msgid "Select the Content Profile content type to load." +msgstr "Wählen Sie den Inhaltstyp der mit dem Benutzerprofil geladen wird aus." + +#: content_profile.rules.inc:85 +msgid "Load @user's @type" +msgstr "@type für @user laden" + +#: content_profile.theme.inc:27 +msgid "edit" +msgstr "Bearbeiten" + +#: content_profile.theme.inc:64 +msgid "View" +msgstr "Ansicht" + +#: content_profile.theme.inc:72 +#: content_profile.module:35 +msgid "Edit" +msgstr "Bearbeiten" + +#: content_profile.module:130 +msgid "Weight" +msgstr "Gewichtung" + +#: content_profile.module:132 +msgid "The weight of content of this content type where ever they appear - this applies to the input form integration as well to the display integration." +msgstr "Die Gewichtung zur Positionierung des Inhalts für diesen Inhaltstyp, wo immer sie auftreten - das gilt für das Eingabeformular und die Ausgabe." + +#: content_profile.module:137 +msgid "Display settings" +msgstr "Anzeigeeinstellungen" + +#: content_profile.module:138 +msgid "Customize the display of this content profile." +msgstr "Die Anzeige des Benutzerprofiles anpassen" + +#: content_profile.module:143 +msgid "User page display style" +msgstr "Stil zur Anzeige der Benutzerprofil-Seiten" + +#: content_profile.module:146 +msgid "Don't display this content profile on the user account page" +msgstr "Das Benutzerprofil nicht auf der Seite des Benutzerkontos anzeigen" + +#: content_profile.module:147 +msgid "Display it as link to the profile content" +msgstr "Einen Link zum Benutzerprofil anzeigen" + +#: content_profile.module:148 +msgid "Display the full content" +msgstr "Den gesamten Inhalt anzeigen" + +#: content_profile.module:149 +msgid "Display the content's teaser" +msgstr "Den Anrißtext anzeigen" + +#: content_profile.module:154 +msgid "Include an edit link to the display" +msgstr "Eines Links zum Bearbeiten anzeigen" + +#: content_profile.module:159 +msgid "Show a link to the content profile creation page, if there is no profile." +msgstr "Eines Links zum Erstellen eines Benutzerprofil anzeigen, wenn keines vorhanden ist." + +#: content_profile.module:161 +msgid "If selected and the user has no profile of this type yet, a link to add one is shown on the user page." +msgstr "Eines Links zum Erstellen eines Benutzerprofil anzeigen, wenn keines vorhanden ist." + +#: content_profile.module:165 +msgid "Profile edit tab" +msgstr "Registerkarte zum Bearbeiten des Benutzerprofils" + +#: content_profile.module:168 +msgid "None" +msgstr "Keine" + +#: content_profile.module:169 +msgid "Show a tab at the user's page" +msgstr "Eine Registerkarte auf der Seite des Benutzerkontos anzeigen" + +#: content_profile.module:170 +msgid "Show a secondary tab below the user's edit tab" +msgstr "Eine zweite Registerkarte unterhalb des Reiters Benutzerkonto bearbeiten" + +#: content_profile.module:175 +msgid "Submit" +msgstr "Speichern" + +#: content_profile.module:267 +msgid "Use this content type as a content profile for users" +msgstr "Diesen Inhaltstyp für das Benutzerprofil verwenden" + +#: content_profile.module:368 +msgid "@type %title has been deleted." +msgstr "@type %title wurde gelöscht." + +#: content_profile.module:393 +msgid "This user already has a content profile of this type. You can only create one profile per user." +msgstr "Der Benutzer hat ein Profil dieses Inhaltstyps. Pro Benutzer kann nur ein Profil erstellt werden" + +#: content_profile.module:367 +#: modules/content_profile_registration.module:254 +msgid "content" +msgstr "Inhalt" + +#: content_profile.module:367 +msgid "@type: deleted %title." +msgstr "@type: gelöscht %title." + +#: content_profile.module:39 +msgid "Content profile" +msgstr "Content Profile / Benutzerprofil" + +#: content_profile.module:40 +msgid "Configure the display and management of this content profile." +msgstr "Anpassen der Anzeige und Verwaltung dieses Benutzerprofils" + +#: content_profile.install:34 +msgid "Profile" +msgstr "Profil" + +#: content_profile.install:36 +msgid "A user profile built as content." +msgstr "Ein Benutzerprofil als Eintrag erstellen." + +#: content_profile.info:0 +msgid "Use content types for user profiles." +msgstr "Verwenden Sie Inhaltstypen für Benutzerprofile." + +#: modules/content_profile_registration.module:31 +msgid "User Registration" +msgstr "Benutzerregistrierung" + +#: modules/content_profile_registration.module:32 +msgid "Customize how this content profile shows up on the user registration page." +msgstr "Anpassen des Benutzerprofils auf der Seite für die Registrierung von Benutzern" + +#: modules/content_profile_registration.module:37 +msgid "Use on Registration" +msgstr "Verwenden für die Registrierung" + +#: modules/content_profile_registration.module:38 +msgid "Use this content type on the user registration page" +msgstr "Diesen Inhaltstyp auf der Seite Benutzer-Registrierung verwenden" + +#: modules/content_profile_registration.module:43 +msgid "Use on administrative user creation form" +msgstr "[fuzzy] Auf den administrativen Seiten der Benutzerverwaltung verwenden" + +#: modules/content_profile_registration.module:44 +msgid "Use this content type when an administrative user creates a new user" +msgstr "Diesen Inhaltstyp auf der Seite Benutzer-Registrierung verwenden, wenn ein neuer Benutzer angelegt wird" + +#: modules/content_profile_registration.module:49 +msgid "Hide form fields" +msgstr "Formularfelder verbergen" + +#: modules/content_profile_registration.module:86 +msgid "Title" +msgstr "Titel" + +#: modules/content_profile_registration.module:93 +msgid "Other form elements (except for required CCK fields)" +msgstr "Andere Formular Elemente (mit Ausnahme von erforderlichen CCK-Feldern)" + +#: modules/content_profile_registration.module:254 +msgid "view" +msgstr "[fuzzy] Anzeige" + +#: modules/content_profile_registration.module:254 +msgid "Content Profile: added %user %type upon registration." +msgstr "Benutzerprofil: %user %type für die Registierung hinzugefügt." + +#: modules/content_profile_registration.info:0 +msgid "Content Profile User Registration" +msgstr "Benutzerprofil für die Benutzer-Registierung" + +#: modules/content_profile_registration.info:0 +msgid "Enable content profile features during user registration" +msgstr "Benutzerprofil für die Benutzer-Registierung aktivieren" + +#: panels/relationships/node_from_user.inc:15 +msgid "Profile Node" +msgstr "Eintrag für das Benutzerprofil" + +#: panels/relationships/node_from_user.inc:17 +msgid "Adds a Content Profile from user context" +msgstr "Das Benutzerprofil zum Kontext des Benutzers hinzufügen" + +#: panels/relationships/node_from_user.inc:56 +msgid "Relationship type" +msgstr "Beziehungstyp" + +#: views/content_profile.views.inc:15 +msgid "Node" +msgstr "Eintrag" + +#: views/content_profile.views.inc:17 +msgid "Create a relationship to a content profile of the user." +msgstr "Eine Relation zum Benutzerprofil erstellen" + +#: views/content_profile_views_handler_relationship.inc:23 +msgid "Content type" +msgstr "Inhaltstyp" + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/translations/hu.po b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/hu.po new file mode 100644 index 0000000000000000000000000000000000000000..14679c1b6211fff5d3a5fb5d57cf3597c3a5a842 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/hu.po @@ -0,0 +1,169 @@ +# Hungarian translation of Content Profile (6.x-1.0-beta4) +# Copyright (c) 2010 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Content Profile (6.x-1.0-beta4)\n" +"POT-Creation-Date: 2010-03-25 17:02+0000\n" +"PO-Revision-Date: 2010-03-25 17:01+0000\n" +"Language-Team: Hungarian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +msgid "Title" +msgstr "Cím" +msgid "Submit" +msgstr "Beküldés" +msgid "content" +msgstr "tartalom" +msgid "view" +msgstr "megtekintés" +msgid "Edit" +msgstr "Szerkesztés" +msgid "None" +msgstr "Nincs" +msgid "Display settings" +msgstr "Megjelenítési beállítások" +msgid "Weight" +msgstr "Súly" +msgid "edit" +msgstr "szerkesztés" +msgid "View" +msgstr "Megtekintés" +msgid "User" +msgstr "Felhasználó" +msgid "Content type" +msgstr "Tartalomtípus" +msgid "Node" +msgstr "Tartalom" +msgid "Profile" +msgstr "Profil" +msgid "@type: deleted %title." +msgstr "@type: %title törölve lett." +msgid "Relationship type" +msgstr "Kapcsolattípus" +msgid "User, whose profile should be loaded" +msgstr "Felhasználó, akinek a profilja betöltésre kerüljön" +msgid "User page display style" +msgstr "A felhasználó oldalának stílusa" +msgid "Include an edit link to the display" +msgstr "A „szerkesztés” hivatkozás megjelenítése" +msgid "" +"If selected and the user has no profile of this type yet, a link to " +"add one is shown on the user page." +msgstr "" +"Kiválasztása esetén, ha a felhasználó még nem rendelkezik " +"profillal, akkor megjelenik egy profil hozzáadása hivatkozás a " +"felhasználó oldalán." +msgid "User Registration" +msgstr "Felhasználó regisztráció" +msgid "@type %title has been deleted." +msgstr "%title @type törölve lett." +msgid "User has content profile" +msgstr "A felhasználónak már van profilja" +msgid "Content Profile Content Type" +msgstr "Tartalomprofil tartalomtípus" +msgid "Select the Content Profile content type to check for." +msgstr "Ki kell választani a tartalomprofilt az ellenőrzéshez." +msgid "@user has his @type created" +msgstr "@user már készített @type típusú elemet" +msgid "Load Content Profile" +msgstr "A tartalomprofil betöltése" +msgid "Content Profile" +msgstr "Tartalomprofil" +msgid "Select the Content Profile content type to load." +msgstr "Ki kell választani a tartalomprofilt a betöltéshez." +msgid "Load @user's @type" +msgstr "@user felhasználó @type típusának betöltése" +msgid "" +"The weight of content of this content type where ever they appear - " +"this applies to the input form integration as well to the display " +"integration." +msgstr "" +"A tartalomprofil tartalom súlya, ahol csak megjelenhet. Ez a " +"beállítás érvényes lesz a beviteli űrlappal és a " +"megjelenítéssel történő együttműködésre is." +msgid "Customize the display of this content profile." +msgstr "A tartalomprofil egyedi megjelenítésének beállításai." +msgid "Don't display this content profile on the user account page" +msgstr "Nem kell megmutatni ezt a tartalomprofilt a felhasználó oldalán" +msgid "Display it as link to the profile content" +msgstr "Csak egy hivatkozás megjelenítése a profil tartalmára" +msgid "Display the full content" +msgstr "A teljes tartalom megjelenítése" +msgid "Display the content's teaser" +msgstr "A tartalom bevezető megjelenítése" +msgid "" +"Show a link to the content profile creation page, if there is no " +"profile." +msgstr "" +"Egy hivatkozás megjelenítése a tartalomprofil készítés oldalra, " +"ha nincs még beküldött profil." +msgid "Profile edit tab" +msgstr "Profil szerkesztése fül" +msgid "Show a tab at the user's page" +msgstr "Menüfül megjelenítése a felhasználó oldalán" +msgid "Show a secondary tab below the user's edit tab" +msgstr "" +"A felhasználó szerkesztés oldalán egy másodlagos menüfül " +"megjelenítése a menüfülek alatt" +msgid "Use this content type as a content profile for users" +msgstr "" +"Ennek a tartalomtípusnak a használata, mint felhasználói " +"tartalomprofil" +msgid "" +"This user already has a content profile of this type. You can only " +"create one profile per user." +msgstr "" +"Ennek a felhasználónak már van ilyen típusú tartalomprofilja. " +"Csak egy profil készíthető felhasználónként." +msgid "Content profile" +msgstr "Tartalomprofil" +msgid "Configure the display and management of this content profile." +msgstr "" +"A tartalomprofil megjelenítésének beállításai és " +"adminisztrációja" +msgid "A user profile built as content." +msgstr "A felhasználó profil felépült, mint tartalom." +msgid "Use content types for user profiles." +msgstr "A tartalomtípus használata felhasználó profilban." +msgid "" +"Customize how this content profile shows up on the user registration " +"page." +msgstr "" +"A tartalomprofil beállítása a felhasználó regisztráció oldalon " +"megjelenéshez" +msgid "Use on Registration" +msgstr "Használat regisztráció során" +msgid "Use this content type on the user registration page" +msgstr "" +"Ennek a tartalomtípusnak a használata a felhasználó regisztráció " +"oldalon" +msgid "Use on administrative user creation form" +msgstr "" +"Használat az adminisztrációs „felhasználó hozzáadása” " +"űrlapon" +msgid "Use this content type when an administrative user creates a new user" +msgstr "" +"Használja ezt a tartalomtípust, ha az adminisztrátor létrehoz egy " +"felhasználót" +msgid "Hide form fields" +msgstr "Űrlapmezők elrejtése" +msgid "Other form elements (except for required CCK fields)" +msgstr "Egyéb űrlapelemek (kivéve a kitöltendő <em>CCK</em> mezők)" +msgid "Content Profile: added %user %type upon registration." +msgstr "" +"Tartalomprofil: %user felhasználóhoz %type típus a regisztráció " +"során hozzá lett adva." +msgid "Content Profile User Registration" +msgstr "Tartalomprofil felhasználó regisztráció" +msgid "Enable content profile features during user registration" +msgstr "A tartalomprofil engedélyezése a felhasználó regisztráció során" +msgid "Profile Node" +msgstr "Profil tartalom" +msgid "Adds a Content Profile from user context" +msgstr "Tartalomprofil hozzáadása a felhasználó környezetből" +msgid "Create a relationship to a content profile of the user." +msgstr "Hivatkozás készítése a felhasználó tartalomprofiljához" diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/translations/ja.po b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/ja.po new file mode 100644 index 0000000000000000000000000000000000000000..b5ad413a44a540313d8a0f3bc66cfaf5dac2819f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/ja.po @@ -0,0 +1,298 @@ +# $Id: ja.po,v 1.1.2.1 2009/12/02 05:07:04 pineray Exp $ +# +# Japanese translation of Drupal (general) +# Copyright PineRay <com.gmail@matsudaterutaka **reverse order**> +# Generated from files: +# content_profile.rules.inc,v 1.1.2.2 2009/03/30 10:20:01 fago +# node_from_user.inc,v 1.1.2.2 2009/08/05 13:41:06 fago +# content_profile.module,v 1.1.2.41 2009/08/05 14:08:34 fago +# content_profile.info,v 1.1.2.1 2008/02/01 16:00:24 fago +# content_profile_registration.info,v 1.1.2.4 2009/04/21 13:59:38 fago +# content_profile_tokens.info,v 1.1.2.1 2009/11/03 14:20:17 fago +# content_profile.views.inc,v 1.1.2.1 2008/09/26 16:09:43 fago +# content_profile.theme.inc,v 1.1.2.9 2009/09/15 15:35:47 fago +# content_profile_registration.module,v 1.1.2.35 2009/09/15 14:27:01 fago +# content_profile.install,v 1.1.2.7 2009/01/09 15:55:07 fago +# content_profile_tokens.module,v 1.1.2.1 2009/11/03 14:20:17 fago +# content_profile_views_handler_relationship.inc,v 1.1.2.3 2009/06/11 15:14:21 fago +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-11-12 17:46+0900\n" +"PO-Revision-Date: 2009-12-02 14:04+0900\n" +"Last-Translator: PineRay <com.gmail@matsudaterutaka **reverse order**>\n" +"Language-Team: Japanese <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: content_profile.rules.inc:15 +msgid "User has content profile" +msgstr "ユーザーにコンテンツプロフィールが存在する" + +#: content_profile.rules.inc:17 +#: panels/relationships/node_from_user.inc:18 +msgid "User" +msgstr "ユーザ" + +#: content_profile.rules.inc:33;76 +msgid "Content Profile Content Type" +msgstr "コンテンツプロフィールのコンテンツタイプ" + +#: content_profile.rules.inc:36 +msgid "Select the Content Profile content type to check for." +msgstr "チェックするコンテンツプロフィールのコンテンツタイプを選択してください。" + +#: content_profile.rules.inc:42 +msgid "@user has his @type created" +msgstr "@user は @type を作成済み" + +#: content_profile.rules.inc:51 +msgid "Load Content Profile" +msgstr "コンテンツプロフィールをロード" + +#: content_profile.rules.inc:53 +msgid "User, whose profile should be loaded" +msgstr "プロフィールをロードするユーザー" + +#: content_profile.rules.inc:56 +#: content_profile.module:260 +#: content_profile.info:0;0 +#: modules/content_profile_registration.info:0 +#: modules/content_profile_tokens.info:0 +#: views/content_profile.views.inc:16;22 +msgid "Content Profile" +msgstr "コンテンツプロフィール" + +#: content_profile.rules.inc:79 +msgid "Select the Content Profile content type to load." +msgstr "ロードするコンテンツプロフィールのコンテンツタイプを選択してください。" + +#: content_profile.rules.inc:85 +msgid "Load @user's @type" +msgstr "@userの@typeをロード" + +#: content_profile.theme.inc:27 +msgid "edit" +msgstr "編集" + +#: content_profile.theme.inc:64 +msgid "View" +msgstr "表示" + +#: content_profile.theme.inc:72 +#: content_profile.module:35 +msgid "Edit" +msgstr "編集" + +#: content_profile.module:130 +msgid "Weight" +msgstr "ウェイト" + +#: content_profile.module:132 +msgid "The weight of content of this content type where ever they appear - this applies to the input form integration as well to the display integration." +msgstr "このコンテンツタイプのコンテンツに使用されるウェイト。表示と同じく入力フォームにも適用されます。" + +#: content_profile.module:137 +msgid "Display settings" +msgstr "表示設定" + +#: content_profile.module:138 +msgid "Customize the display of this content profile." +msgstr "このコンテンツタイプの表示をカスタマイズ。" + +#: content_profile.module:143 +msgid "User page display style" +msgstr "ユーザーページでの表示スタイル" + +#: content_profile.module:146 +msgid "Don't display this content profile on the user account page" +msgstr "このコンテンツプロフィールをユーザーアカウントページで表示しない" + +#: content_profile.module:147 +msgid "Display it as link to the profile content" +msgstr "プロフィールコンテンツへのリンクとして表示" + +#: content_profile.module:148 +msgid "Display the full content" +msgstr "完全なコンテンツを表示" + +#: content_profile.module:149 +msgid "Display the content's teaser" +msgstr "コンテンツのティーザーを表示" + +#: content_profile.module:154 +msgid "Include an edit link to the display" +msgstr "編集リンクを表示に含める" + +#: content_profile.module:159 +msgid "Show a link to the content profile creation page, if there is no profile." +msgstr "プロフィールがなければ、コンテンツプロフィールの作成ページへのリンクを表示。" + +#: content_profile.module:161 +msgid "If selected and the user has no profile of this type yet, a link to add one is shown on the user page." +msgstr "選択されていて、ユーザーにこのタイプのプロフィールがまだ存在していなければ、プロフィールを追加するためのリンクをユーザーページに表示します。" + +#: content_profile.module:165 +msgid "Profile edit tab" +msgstr "プロフィール編集タブ" + +#: content_profile.module:168 +msgid "None" +msgstr "無し" + +#: content_profile.module:169 +msgid "Show a tab at the user's page" +msgstr "ユーザーページにタブを表示" + +#: content_profile.module:170 +msgid "Show a secondary tab below the user's edit tab" +msgstr "ユーザーの編集タブの下にセカンダリータブを表示" + +#: content_profile.module:175 +msgid "Submit" +msgstr "送信" + +#: content_profile.module:267 +msgid "Use this content type as a content profile for users" +msgstr "このコンテンツタイプをユーザーのコンテンツプロフィールとして使用" + +#: content_profile.module:368 +msgid "@type %title has been deleted." +msgstr "@type %title が削除されました。" + +#: content_profile.module:392 +msgid "This user already has a content profile of this type. You can only create one profile per user." +msgstr "このタイプのコンテンツプロフィールがすでに存在します。ひとりのユーザーにつきひとつのプロフィールしか作成できません。" + +#: content_profile.module:367 +#: modules/content_profile_registration.module:262 +msgid "content" +msgstr "コンテンツ" + +#: content_profile.module:367 +msgid "@type: deleted %title." +msgstr "@type: %title が削除されました。" + +#: content_profile.module:39 +msgid "Content profile" +msgstr "コンテンツプロフィール" + +#: content_profile.module:40 +msgid "Configure the display and management of this content profile." +msgstr "コンテンツプロフィールの表示と管理を設定します。" + +#: content_profile.install:34 +msgid "Profile" +msgstr "プロフィール" + +#: content_profile.install:36 +msgid "A user profile built as content." +msgstr "コンテンツとして作成するユーザープロフィール。" + +#: content_profile.info:0 +msgid "Use content types for user profiles." +msgstr "ユーザープロフィールにコンテンツタイプを使用します。" + +#: modules/content_profile_registration.module:31 +msgid "User Registration" +msgstr "ユーザー登録" + +#: modules/content_profile_registration.module:32 +msgid "Customize how this content profile shows up on the user registration page." +msgstr "このコンテンツプロフィールをユーザー登録ページでどのように表示するかカスタマイズします。" + +#: modules/content_profile_registration.module:37 +msgid "Use on Registration" +msgstr "ユーザー登録で使用" + +#: modules/content_profile_registration.module:38 +msgid "Use this content type on the user registration page" +msgstr "このコンテンツタイプをユーザー登録ページで使用します。" + +#: modules/content_profile_registration.module:43 +msgid "Use on administrative user creation form" +msgstr "管理画面のユーザー追加フォームで使用" + +#: modules/content_profile_registration.module:44 +msgid "Use this content type when an administrative user creates a new user" +msgstr "このコンテンツタイプを管理者が新しいユーザーを作成する際に使用します。" + +#: modules/content_profile_registration.module:49 +msgid "Hide form fields" +msgstr "フォームフィールドを非表示" + +#: modules/content_profile_registration.module:50 +msgid "Hide fields from the user registration form. Required fields cannot be hidden and are not shown here." +msgstr "ユーザー登録フォームでフィールドを非表示にします。必須のフィールドは非表示にできず、ここには表示されていません。" + +#: modules/content_profile_registration.module:87 +msgid "Title" +msgstr "タイトル" + +#: modules/content_profile_registration.module:94 +msgid "Other form elements (except for required CCK fields)" +msgstr "その他のフォーム要素(必須のCCKフィールドを除く)" + +#: modules/content_profile_registration.module:262 +msgid "view" +msgstr "表示" + +#: modules/content_profile_registration.module:262 +msgid "Content Profile: added %user %type upon registration." +msgstr "コンテンツプロフィール: %user の %type をユーザー登録で追加しました。" + +#: modules/content_profile_tokens.module:73;85;88 +msgid "WARNING - raw user input" +msgstr "注: ユーザーが入力した RAW データ" + +#: modules/content_profile_tokens.module:84;85 +msgid "Requestor:" +msgstr "要求する側:" + +#: modules/content_profile_tokens.module:87;88 +msgid "Requestee:" +msgstr "要求される側:" + +#: modules/content_profile_registration.info:0 +msgid "Content Profile User Registration" +msgstr "コンテンツプロフィールでユーザー登録" + +#: modules/content_profile_registration.info:0 +msgid "Enable content profile features during user registration" +msgstr "コンテンツプロフィールの機能をユーザー登録で有効にします" + +#: modules/content_profile_tokens.info:0 +msgid "Content Profile Tokens" +msgstr "" + +#: modules/content_profile_tokens.info:0 +msgid "Add user tokens for content profiles." +msgstr "コンテンツプロフィールにユーザートークンを追加します。" + +#: panels/relationships/node_from_user.inc:15 +msgid "Profile Node" +msgstr "プロフィールノード" + +#: panels/relationships/node_from_user.inc:17 +msgid "Adds a Content Profile from user context" +msgstr "ユーザーコンテクストからコンテンツプロフィールを追加" + +#: panels/relationships/node_from_user.inc:61 +msgid "Relationship type" +msgstr "リレーションシップのタイプ" + +#: views/content_profile.views.inc:15 +msgid "Node" +msgstr "ノード" + +#: views/content_profile.views.inc:17 +msgid "Create a relationship to a content profile of the user." +msgstr "ユーザーのコンテンツプロフィールにリレーションシップを作成。" + +#: views/content_profile_views_handler_relationship.inc:23 +msgid "Content type" +msgstr "コンテンツタイプ" + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/translations/sv.po b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/sv.po new file mode 100644 index 0000000000000000000000000000000000000000..db59fd4b7dfd321f629da16621eb597cc95b0231 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/translations/sv.po @@ -0,0 +1,273 @@ +# $Id: sv.po,v 1.1.2.1 2009/04/21 00:11:57 seals Exp $ +# +# Swedish translation of Drupal (content_profile) +# Generated from files: +# content_profile.panels.inc,v 1.1.2.1 2009/01/04 12:02:19 fago +# content_profile.rules.inc,v 1.1.2.1 2009/01/07 11:36:36 fago +# content_profile.module,v 1.1.2.32 2009/01/07 10:58:05 fago +# content_profile.info,v 1.1.2.1 2008/02/01 16:00:24 fago +# content_profile_registration.info,v 1.1.2.3 2008/07/24 10:16:40 fago +# content_profile.views.inc,v 1.1.2.1 2008/09/26 16:09:43 fago +# content_profile.theme.inc,v 1.1.2.8 2009/01/07 10:58:05 fago +# content_profile_registration.module,v 1.1.2.25 2009/01/07 11:02:28 fago +# content_profile.install,v 1.1.2.6 2009/01/04 11:30:28 fago +# content_profile_views_handler_relationship.inc,v 1.1.2.2 2008/11/04 03:57:08 jgraham +# +msgid "" +msgstr "" +"Project-Id-Version: Content Profile 6.x\n" +"POT-Creation-Date: 2009-04-21 01:45+0200\n" +"PO-Revision-Date: 2009-04-21 02:07+0100\n" +"Last-Translator: Magnus Gunnarsson <seals@passagen.se>\n" +"Language-Team: drupalsverige.se\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: content_profile.panels.inc:14 +msgid "Profile Node from user" +msgstr "Nodprofil från användare" + +#: content_profile.panels.inc:16 +msgid "Adds a Content Profile from user context" +msgstr "Lägger till en innehållsprofl från användares sammanhang" + +#: content_profile.panels.inc:17 +#: content_profile.rules.inc:17 +msgid "User" +msgstr "Användare" + +#: content_profile.panels.inc:54 +msgid "Relationship type" +msgstr "Typ av släktskap" + +#: content_profile.rules.inc:15 +msgid "User has content_profile" +msgstr "Användare har content_profile" + +#: content_profile.rules.inc:33;76 +msgid "Content Profile Content Type" +msgstr "Innehållstyp för innehållsprofil" + +#: content_profile.rules.inc:36 +msgid "Select the Content Profile content type to check for." +msgstr "Välj innehållstyp att kontrollera för innehållsprofil." + +#: content_profile.rules.inc:42 +msgid "@user has his @type created" +msgstr "@user har skapat sin @type" + +#: content_profile.rules.inc:51 +msgid "Load Content Profile" +msgstr "Ladda innehållsprofil" + +#: content_profile.rules.inc:53 +msgid "User, whose profile should be loaded" +msgstr "Användare vars profil skall laddas" + +#: content_profile.rules.inc:56 +#: content_profile.module:249 +#: content_profile.info:0;0 +#: modules/content_profile_registration.info:0 +#: views/content_profile.views.inc:16;22 +msgid "Content Profile" +msgstr "Innehållsprofil" + +#: content_profile.rules.inc:79 +msgid "Select the Content Profile content type to load." +msgstr "Välj innehållstyp att ladda för innehållsprofilen" + +#: content_profile.rules.inc:85 +msgid "Load @user's @type" +msgstr "Ladda @type för @user" + +#: content_profile.theme.inc:27 +msgid "edit" +msgstr "redigera" + +#: content_profile.theme.inc:64 +msgid "View" +msgstr "Visa" + +#: content_profile.theme.inc:72 +#: content_profile.module:30 +msgid "Edit" +msgstr "Redigera" + +#: content_profile.module:119 +msgid "Weight" +msgstr "Vikt" + +#: content_profile.module:121 +msgid "The weight of content of this content type where ever they appear - this applies to the input form integration as well to the display integration." +msgstr "Vikten för innehållet för denna innehållstyp där de återfinns - detta gäller integrationen med inmatningsformuläret såväl som integrationen med visningen." + +#: content_profile.module:126 +msgid "Display settings" +msgstr "Inställningar för visning" + +#: content_profile.module:127 +msgid "Customize the display of this content profile." +msgstr "Anpassa visningen för denna innehållsprofil." + +#: content_profile.module:132 +msgid "User page display style" +msgstr "Stil för visning av användarsida" + +#: content_profile.module:135 +msgid "Don't display this content profile on the user account page" +msgstr "Visa inte denna innehållsprofil på sidan för användarens konto" + +#: content_profile.module:136 +msgid "Display it as link to the profile content" +msgstr "Visa det som en länk till profilens innehåll" + +#: content_profile.module:137 +msgid "Display the full content" +msgstr "Visa det fullständiga innehållet" + +#: content_profile.module:138 +msgid "Display the content's teaser" +msgstr "Visa innehållets sammanfattning" + +#: content_profile.module:143 +msgid "Include an edit link to the display" +msgstr "Inkludera en redigeringslänk till visningen" + +#: content_profile.module:148 +msgid "Show a link to the content profile creation page, if there is no profile." +msgstr "Visa en länk till sidan för att skapa en innehållsprofil, om det inte finns någon profil." + +#: content_profile.module:150 +msgid "If selected and the user has no profile of this type yet, a link to add one is shown on the user page." +msgstr "Om vald och användaren inte har någon profil av denna typ ännu visas en länk för att lägga till en på användarens sida." + +#: content_profile.module:154 +msgid "Profile edit tab" +msgstr "Flik för redigering av profil" + +#: content_profile.module:157 +msgid "None" +msgstr "Ingen" + +#: content_profile.module:158 +msgid "Show a tab at the user's page" +msgstr "visa en flik på användarens sida" + +#: content_profile.module:159 +msgid "Show a secondary tab below the user's edit tab" +msgstr "Visa en sekundär flik under användarens redigeringsflik" + +#: content_profile.module:164 +msgid "Submit" +msgstr "Skicka" + +#: content_profile.module:256 +msgid "Use this content type as a content profile for users" +msgstr "Använd denna innehållstyp som innehållsprofil för användare" + +#: content_profile.module:357 +msgid "@type %title has been deleted." +msgstr "%title (@type) har raderats." + +#: content_profile.module:377 +msgid "This user has already a content profile of this type. You can only create one profile per user." +msgstr "Denna användare har redan en innehållsprofil av denna typ. Du kan enbart skaåa en profil per användare." + +#: content_profile.module:356 +#: modules/content_profile_registration.module:161 +msgid "content" +msgstr "innehåll" + +#: content_profile.module:356 +msgid "@type: deleted %title." +msgstr "@type: raderade %title." + +#: content_profile.module:34 +msgid "Content profile" +msgstr "Innehållsprofil" + +#: content_profile.module:35 +msgid "Configure the display and management of this content profile." +msgstr "Konfigurera visningen och hanteringen av denna innehållsprofil." + +#: content_profile.module:0 +msgid "content_profile" +msgstr "content_profile" + +#: content_profile.install:34 +msgid "Profile" +msgstr "Profil" + +#: content_profile.install:36 +msgid "A user profile built as content." +msgstr "En användarprofil uppbyggd som innehåll." + +#: content_profile.info:0 +msgid "Use content types for user profiles." +msgstr "Använd innehållstyp för användareprofiler." + +#: modules/content_profile_registration.module:56 +msgid "User Registration" +msgstr "Användarregistrering" + +#: modules/content_profile_registration.module:57 +msgid "Customize how this content profile shows up on the user registration page." +msgstr "Anpassa hur denna innehållsprofil skall visas på sidan för användarens registrering." + +#: modules/content_profile_registration.module:64 +msgid "Use on Registration" +msgstr "Använd under registrering" + +#: modules/content_profile_registration.module:65 +msgid "Use this content type on the user registration page" +msgstr "Använd denna innehållstyp på användarens sida för registrering" + +#: modules/content_profile_registration.module:72 +msgid "Hide these fields during registration" +msgstr "Göm dessa fält under registrering" + +#: modules/content_profile_registration.module:79 +msgid "There are no fields defined, so registration integration is disabled." +msgstr "Det finns inga fält definierade, så integrering under registrering är inaktiverad." + +#: modules/content_profile_registration.module:122 +msgid "Field Group: " +msgstr "Fältgrupp: " + +#: modules/content_profile_registration.module:161 +msgid "view" +msgstr "visa" + +#: modules/content_profile_registration.module:161 +msgid "Content Profile: added %user %type upon registration." +msgstr "Innehållsprofil: lade till %user %type under registrering." + +#: modules/content_profile_registration.module:0 +msgid "content_profile_registration" +msgstr "content_profile_registration" + +#: modules/content_profile_registration.info:0 +msgid "Content Profile User Registration" +msgstr "Registrering av användares innehållsprofiler" + +#: modules/content_profile_registration.info:0 +msgid "Enable content profile features during user registration" +msgstr "Aktivera innehållsprofils funktioner under användarregistrering" + +#: views/content_profile.views.inc:15 +msgid "Node" +msgstr "Nod" + +#: views/content_profile.views.inc:17 +msgid "Create a relationship to a content profile of the user." +msgstr "Skapa ett släktskap till en innehållsprofil för användaren." + +#: views/content_profile_views_handler_relationship.inc:23 +msgid "Content type" +msgstr "Innehållstyp" + diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/views/content_profile.views.inc b/drupal/sites/default/boinc/modules/contrib/content_profile/views/content_profile.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..263a807c872ea3893bba660bba4a9c399268d9ee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/views/content_profile.views.inc @@ -0,0 +1,42 @@ +<?php +// $Id: content_profile.views.inc,v 1.1.2.1 2008/09/26 16:09:43 fago Exp $ + +/** + * @file content_profile.views.inc + * Provides support for the Views module. + */ + +/** + * Implementation of hook_views_data_alter(). + */ +function content_profile_views_data_alter(&$data) { + // node relationship for profiles + $data['users']['content_profile_rel'] = array( + 'group' => t('Node'), + 'title' => t('Content Profile'), + 'help' => t('Create a relationship to a content profile of the user.'), + 'relationship' => array( + 'handler' => 'content_profile_views_handler_relationship', + 'base' => 'node', + 'base field' => 'uid', + 'label' => t('Content Profile'), + ), + ); +} + + +/** + * Implementation of hook_views_handlers(). + */ +function content_profile_views_handlers() { + return array( + 'info' => array( + 'path' => drupal_get_path('module', 'content_profile') .'/views', + ), + 'handlers' => array( + 'content_profile_views_handler_relationship' => array( + 'parent' => 'views_handler_relationship', + ), + ), + ); +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/content_profile/views/content_profile_views_handler_relationship.inc b/drupal/sites/default/boinc/modules/contrib/content_profile/views/content_profile_views_handler_relationship.inc new file mode 100644 index 0000000000000000000000000000000000000000..800bc32c393e8b15400343e3b749b2cfe5dd7e5b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/content_profile/views/content_profile_views_handler_relationship.inc @@ -0,0 +1,57 @@ +<?php +// $Id: content_profile_views_handler_relationship.inc,v 1.1.2.4 2010/01/12 10:05:01 fago Exp $ +// @file + +/** + * Specialized relationship handler to adding content profiles. + */ +class content_profile_views_handler_relationship extends views_handler_relationship { + function option_definition() { + $options = parent::option_definition(); + + $options['type'] = array('default' => ''); + return $options; + } + + /** + * Adds a form element for choosing the right content type. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['type'] = array( + '#type' => 'radios', + '#title' => t('Content type'), + '#default_value' => $this->options['type'], + '#options' => content_profile_get_types('names'), + '#required' => TRUE, + ); + } + + /** + * Called to implement a relationship in a query. + */ + function query() { + // Figure out what base table this relationship brings to the party. + $join = new views_join(); + $join->definition = array( + 'table' => 'node', + 'field' => 'uid', + 'left_table' => !empty($this->relationship) ? $this->relationship : 'users', + 'left_field' => 'uid', + 'extra' => array( + array('field' => 'type', 'value' => $this->options['type']), + ), + ); + + if (!empty($this->options['required'])) { + $join->definition['type'] = 'INNER'; + } + + $join->construct(); + $this->ensure_my_table(); + + $alias = $join->definition['table'] .'_'. $join->definition['left_table']; + $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/API.txt b/drupal/sites/default/boinc/modules/contrib/ctools/API.txt new file mode 100644 index 0000000000000000000000000000000000000000..d54c70089c9911ed0a7c695225d5db106ca71e18 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/API.txt @@ -0,0 +1,102 @@ +API.txt: $Id$ + +This file contains a log of changes to the API. +API version 1.9 + Introduce 'object factory' to export schema, allowing modules to control + how the exportable objects are instantiated. + Introduce 'hook_ctools_math_expression_functions_alter'. + +API version 1.8 + Introduce 'get base contexts' callback to all tasks to facilitate + Page Manager's site template extracting contexts from the environment. + Introduce 'ctools_content_editable' function and the corresponding + 'check editable' callback on all content types to determine if a + content type can be edited based upon configuration. + Introduce utility.inc and move some code to it. + Introduce page-wizard.inc and a "page_wizard" type plugin for Page Manager. + +API version 1.7.2 + Allow Export UI to automatically have wizards by setting 'use wizard' => TRUE + Moved the Panels Stylizer module into CTools so that the UI can be + used to manage styles for modules other than Panels. + Introduce ctools_access_ruleset module for customizable access rulesets. + Introduce ctools_custom_content module for customizable content panes. + Add 'convert default' as a converter keyword for context implementations. + Instead of reverting $context->title this will cause %context without + :converter to use a default converter. + +API version 1.7.1 + Introduce 'modal return' and 'ajax return' to wizard.inc to allow + wizard owners to process their own ajax/modal output. + Introduce math-expr.inc to allow simple math expression parsing. + +API version 1.7 + Introduce the export-ui plugin. This introduces new keys to the 'export' + section of schema: 'primary key', 'key name'. + Introduce ctools_export_crud_ functions to provide CRUD access to most + exportables. This introduces several optional callback keys to the + 'export' section of the schema to provide overrides. + Introduce auto-submit.js. Forms may now be set to auto submit just by + adding appropriate classes. + Provide new default functions for bulk export. This may make items that + were previously not bulk exportable due to missing 'list' callback + appear in the bulk export UI. + +API version 1.5 + Add two new alter hooks: page_manager_operations_alter and + page_manager_variant_operations_alter to allow modules to add tabs + to any page manager page. + +API version 1.4: + Allow themes to provide APIs which includes default pages of all types. + Intorduce ctools_css_add_css() to allow private file systems to have generated CSS. + Introduce initial build of stylizer.inc to allow UI configurable styles. + Introduce 'cache warming' feature. Use 'ctools-use-ajax-cache' or + 'ctools-use-modal-cache'. Doing so will cause content to be fetched + via AJAX on page load and kept warm in a cache for instant responses + to clicks. + Generalized ctools_add_css(). + Generalized ctools_add_js(). + Generalized ctools_image_path(). + Make global hooks for plugin definition optional through a 'use hooks' + plugin option. + +API version 1.3.2: + Introduce 'export callback' to individual fields in export.inc + +API version 1.3.1: + #649144 by neclimdul: Expand ctools_include() to work for other modules. + +API version 1.3: + Introduce ctools_jump_menu(). + Change plugins to no longer need magic function. Can now use $plugin = array(...) instead. + +API version 1.2: + Introduce ctools_set_variable_token(). + Introduce ctools_set_callback_token(). + Introduce cleanstring tool. See cleanstring.inc + Introduce page_manager_get_current_page(). + Introduce ctools_ajax_command_redirect(). + Introduce ctools_ajax_command_reload(). + Introduce ctools_ajax_command_submit(). + Introduce ctools_static(). + Introduce ctools_modal_command_loading(). + +API version 1.1.1: + Introduce ctools_plugin_get_class() and ctools_plugin_load_class() + Introduce ctools_ajax_command_attr(). + Introduce ctools_set_page_token(). + +API version 1.1.0: + delegator module destroyed, replaced by page manager. All 'task' and 'task_handler' plugins + now owned by page_manager. Update plugin hooks accordingly. The filename for defaults + for pages and handlers should now be MODULE.pages_default.inc + + The task_type plugin has been removed. + + Task handlers no longer have a separate UI. While task handlers can still + be separated from pages for other purposes, they will probably need + to implement their own UI to do it. + +API version 1.0: + Initial CTools API version. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/CHANGELOG.txt b/drupal/sites/default/boinc/modules/contrib/ctools/CHANGELOG.txt new file mode 100644 index 0000000000000000000000000000000000000000..d8f0d1120f4d71905744b8f85406267dcba84ad6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/CHANGELOG.txt @@ -0,0 +1,368 @@ +Current API VERSION: 1.8. See API.txt for more information. +ctools 6.x-dev +============== +#959206: If a context is not set when rendering content, attempt to guess the context (fixes Views panes where "From context" was added but pane was never edited.) +#967590: HTTP Response is not part of panels, erroneously refers to being so. +#911362 by alex_b: Facilitate plugin cache resets for tests. +#998870 by Amitaibu: Fix notice when content has no icon by using function already designed for that. +#1030068 by stella: Fix parsing of tokens with : in them. + +ctools 6.x-1.8 (2010-Oct-29) +============== +#856636: Fix warnings on update. +#866524: "Custom" content type could cause crash if trying to reuse it without activating the custom content type module. +#870820 by EclipseGc: ctools_export_crud_import() passed wrong arguments to import callback, if defined. +Improve the task system to make it possible for Panels Everywhere to get more contexts. +#718368: Ignore query string when testing js and css files for inclusion during AJAX requests. +#690648 by awolfey: User signature content type. +#874960 by yhahn: Export UI goes to wrong path on revert. +#868410: Make transparency work on modal backdrop in IE. +#872340: AJAX framework used wrong URLs with i18n and CSS files. +#609246: Create variant to handle 403, 404 and 301 redirects for non-page page responses. +#870466: Invisible steps broken by too aggressive of a test for valid wizard steps. This broke Mini Panel layout change in Panels. +#872804: Export UI delete query failing to get table prefix thanks to PHP oddity. +#867864: Fix a admin title and edit link problems with custom content types. +#812744: Did not quite get query string removal working earlier, causing random breakages to AJAX requests. +#866622 by dkinzer: Fix dimensions.js to not crash on undefined items. +#215927: Allow exposed form blocks to inherit the current path. +#875020: Remove defaults for "API" in export section of schema as "No API version" is a possible option. +Activating export-ui based modules caused warnings (that did not actually cause problems) on the modules page. +#887812 by ayalon: Fix javascript crash bug. +#848580: Re-organize form submission in modals so that wysiwyg can detach upon submit. +#872072: Allow the modal to be vastly more customized. +#873616: Invalid SQL in term_parent access plugin. +#883490: Page manager "page" task needed to validate that % was not used in the first part of a path as that is not supported by Drupal menu system. +#883914: Ensure content pane validity before attemping to use. +#884092: Fix stylizer error message that warns you when there are no modules utilizing stylizer. +#831922 by tizzo: Make ctools_build_form() better support #ahah by properly rebuilding forms when necessary. +#867554: Accidentally binding modal javascript to buttons that were not inputs outside of the modal. +#879438: Change require_once to include_once when including plugin files in case plugins have disappeared. +#896660 by zoo33: Export-UI used wrong object name in descript of export key field. +New "Page wizards" to more easily create well-known types of pages in Page Manager. +#891682 by Dave Reid: Have modal title use the page title if no title was set on the form. +Add documentation for the modal. +#867120: %title was not being properly honored in keyword substitutions. +#856050 by Itangalo: Improve help text regarding tokens and substitutions. +#908104 by naxoc: Provide an option the comments anchor like theme_comment_wrapper does. +#911396 by alex_b: Prevent notices in export UI. +#883902 by hefox: Remove dependency on color.module. +#916532 by swentel: Fix css.inc to not overwrite selectors when used multiple times. +#919768 by mikey_p: Allow url options to be sent to ctools_ajax_command_url(). +#926972 by Amitaibu: Provide automated integration with Advanced Help. +#358953 by cedarm: Allow term context to return lowercase, spaces to dashes versions of terms. +#916796 by swentel: CSS properties with : in them could be destroyed by CSS filter. +#931434 by EclipseGc: Argument plugin for node revision ID. +#910656: CTools AJAX sample wizard demo "domesticated" checkbox value not stored. +#913640 by mavimo: Correct documentation error on ctools_static() +#922442 by EugenMayer, neclimdul and voxpelli: Make sure ctools_include can handle '' or NULL directory. +#919956 by traviss359: Correct example in wizard advanced help. +#942968: Fix taxonomy term access rule with tag term vocabs. +#840344: node add argument had crufty code causing notices. +#944462 by longhairedgit: Invalid character in regex causes rare notice. +Add detach event to modal close so that wysiwyg can detach the editor. +#955348: Lack of redirect on "Update" button in Page Manager causing data loss sometimes. +#941778: Update and save button should not appear in the "Add variant" path. + +ctools 6.x-1.7 (2010-Jul-26) +============== +Deprecated the callback-based 'defaults' in favor of the identical 'process' (plugin system). Consequently, moved the content_type plugin over to use 'process' instead of the 'defaults' callback. +Added a ctools.api.php file and began documenting some of our api/hooks there. +Changed all hook_ctools_plugin_directory() implementations to use the more informative variable naming scheme. +#817612 by elstudio: Fix validation error that was making it impossible to add 'Existing node' content_types. +#787644 by Amitaibu and merlinofchaos: Introduce export-ui and auto-submit. See API.txt for more. +Update the plugin system documentation, and clean up plugin system logic. +#827498: Allow the 'custom' content type to be re-usable and exportable. +#827370 by dereine: Allow the new auto-submit.js to allow a single class that causes every element in the form to auto-submit. +#717036: Add a check to prevent CSS cache files from being cleared on a cron run. +Partial reversion of #742832. +#767046: Current theme selection rule was broken. +Improve the "Edit panel" tab so that Panels Everywhere can use a different name for site template, and Panels can direct it to the most appropriate tab in the editor. +#828352: Recent improvement to allow selection of fields to display in pane caused summary styles to break. +#764006 by drifter: Fix warning when using Panels Everywhere and views content panes together. +#467898 by mikeker: Allow taxonomy term argument to be restricted to a particular set of vocabularies. +#829582 by dmitrig01: apostrophes as data keys in exports would not properly be escaped, breaking the export. +#845540 by Dave Reid: cleanstring.inc had accidental dependency on pathauto. +#755954 by killes: Add relationship plugin to get node edit form context from node context. +#755988 by killes: Render form id, build id and token as part of the form buttons context. +#756118 by killes: node_form_author.inc sets content regardless of content being present. +#783408 by hefox: Make sure empty arguments are properly translated to NULL when passed to Views. +#749398 by harijari: Properly support new column added for signatures in Drupal 6.13. +#815164 by DeFR: Replace fragile server side cache of aggregated .js and .css with more robust embedded .js communicating this information. +#667504 by Jen Lampton: Allow node title to be linked to the node. +#830274 by Amitaibu: Wrong value passed to ctools_export_crud_load_all() by the default UI plugin. +#843280 by Amitaibu: Export UI would WSOD on delete. +#728486 by elliotttf: Fix PHP 5.3 compatibility. +#635730 by dereine and merlinofchaos: Fix page title pane to show actual title. Allow the tag and tag class and id to be specified in pane settings. +#842882 by Amitaibu: Safer handling of determing if an object is new or updated when using ctools_export_crud_save(). +#826074 by Amitaibu: Provide more defaults in schema for new Export UI settings. +#715546 by jsfwd: Term list content type didn't get proper first/last classes. +#731950: Prevent warning if task has invalid subtasks callback. +#831592: Context: Taxonomy vocabulary would not save vocabulary value. +#836828 by jmiccolis: ctools_include() would try to include again even though it was trying to statically cache a list of files already included. +#843042: export-ui delete button did not work. +#847682 by dagmar: Allow export.inc controlled objects to have data that exists in sibling tables to enable integration with exportables.module. +Allow Views to use their exposed filters as pane configuration. This is under the "Allow" settings in the Content pane display. +#849418: "Custom" content type was accidentally losing context substitutions created when reusable custom content types went in. +Moved Panels stylizer UI to CTools. If you use Panels Stylizer, be sure to update Panels at the same time. +Introduce ctools_access_ruleset module for customizable access rulesets. +Introduce ctools_custom_content module for customizable content panes and move the associated UI code to the module. +Restore a less aggressive plugin caching. +#854190 by Amitaibu: Provide a nicer experience with stylizer if there are no stylizer-enabled modules running. +#737602: Generic NOT checkbox for all access tests. +#735922 by daniboy: Allow the redirect command to have a delay. +#704132: Fix broken term_parent access plugin. +#596212 by KoCo: Fix warning message if using taxonomy terms context but no valid terms were found. +#657652: PHP Access rules become uneditable if they had no description. +#680778 by hefox: Taxonomy synonyms not showing correctly in term list content type. +#617678: Improve 'back' button handling during adding a page in page manager. +#817810: Search menu retooling caused the title of search pages to get lost. +#505132: Fix CSS caching to truly work on private filesystem now. +#707990: Add default converters and a default converter to user context to ease integration with realname.module. +#592986: Allow "text-transform" in user-generated CSS. +#507092: Add a "view" context, meaning you can load a view into a context and then display individual rows from that view as panes. +#696402 by pokurek: Prevent node add/edit contexts from getting into infinite loops. +#609424: Book relationship plugin was completely non-functional. +#709242: Required contexts would lose keyword and identifier when transfering context from one system into the subsystem. +#860306 by jcmarco: "Substitutions" fieldset would not open due to missing js. +#861778 by ayalon: Hold session ID for anonymous users when using the object cache so wizards can work for anonymous. +#846408: Increase #delta in reorder weights so that more than 21 variants can be used. +#827310: Node comments content type should not display comments if the node is configured to disable them. +#622570 by omerida: Add an option to display the comment forbidden information if the comment form cannot be displayed in comment form content type. +#863296: Do not leave NULL plugins left by searching for nonexistant plugins in the list when getting all plugins. +#853256 by swentel: Allow the normal node view content types to support CCK hosted build modes like Views does. +#865392 by Amitaibu: Auto-guess ctools ajax class with element associations. + +ctools 6.x-1.6 (2010-Jun-1) +============== +(No changes - 1.5 release was improperly tagged) + +ctools 6.x-1.5 (2010-May-28) +============== +#804198: CTools AJAX framework did not work properly with javascript aggregation. +Handle forms passing through required contexts properly. +Add operation alter tooks to let modules add items to Page Manager pages. +Partial rollback of #711664 - central-hook-based plugin definition no longer defaults to FALSE, as this caused widespread unexpected behavior in modules using ctools plugins. +#708926: Remove dependency-busting call to panels_get_path(). +Do not allow Views Content Pane displays to be selected by the legacy Views content connector; based on #791960. +#737434 by nealeyoung: Make the node_updated content_type plugin actually do what it advertises and output last change time. + +ctools 6.x-1.4 (2010-May-19) +============== +#686764: Update page tokens to use actual page rendering mechanism rather than the tokens which causes them to appear as having content even when empty. +Retool the page elements to render last and not use the token method. +Allow themes to provide default pages so that Panels Everywhere enabled themes can provide layout variants for the site template. +Initial inclusion of the stylizer plugin to create user customizable styles from pre-configured base styles. +#708154: Update and Save would leave forms in an older state, causing some forms to lose data (particularly the Panels content form). +#467948 by hefox: Allow the vocabulary context to be used by the vocabulary selector access plugin. +#686052 by Scott Reynolds: Allow for cache warming. (See API.txt) +#686726 by ayalon: Access plugin to mimic the block path configuration item. +#484340 by catch: Fix bug in token integration. +#709754 by yhahn: Add export_module flag to all default objects so that we can tell where they came from. +#709840 by thsutton: Improper test of AND when displaying access summaries. +#709874 by thsutton: Fix improper test in context exists. +#707826 by marcvangend: Add a relationship to get multiple terms from a node. +#711922 by jonskulski: Do not print empty H1 tag if no title in page_title content. +#703040 by neclimudul: Harden plugin loading against accidental variable overwriting. +#710490 by thsutton: Fix use of error_get_last() which only appears in PHP 5.2. +#716288 by alex_b: Clear more caches when clearing static caches for install/deployment purposes. +#715118 by neclimdul: Add abstract hints to the classes in plugins.inc. +#723296 by andrewlevine: Generalize more of CTools helpers so they can be used for non-CTools files. +#726320 by gordon: Allow the CTools wizard to have query strings in the wizard path. +#711664 by meclimdul: Make the 'hook' version of plugins now optional and improve code around it. +#745468 by alevine and Scott Reynolds: Make ajax better able to know what .js/.css was already on the page. +#722246: Search tabs not quite right, particularly with retaining keywords across tabs. This mostly fixes. +#709754 followup by yhahn: Improved documentation for export.inc +#565808 by cha0s, zroger and davereid: Backport nojs handling from D7. +#704132 by killes: Allow access/selection rule based on whether taxonomy term has a parent. +#747588 by mikeker: Add taxonomy description to context tokens. +#741588 by Jody Lynn: add db_rewrite_sql() to comments pane query to match core. +#531366 by mikeker: Move token substitutions to prior to filtering in custom content type. This could have some effects on existing installs. +#718028 by redben: Improved documentation for wizard.inc +#750004 by jhedstrom: Comment pane ignores node comment display setting. +#752960 by mgriego: Redirect destination on 'delete' in admin links could be wrong. +#754234 by killes: Node form content types not showing up due to logic error. +#754594 by lavamind: Add a "book children" content type. +Ensure imagefilter() exists before use, as it may not depending on how PHP was built. +#798526 by jasonn1234: expand server-side control over modal js settings to include background opacity and color. +#742832 by c960657: cache file system scans in ctools_plugin_load_includes(). +#758750 by mgriego, snufkin: Fix extra whitespace being added to exported scalars. +#789598 by c960657: Pass block titles through check_plain(). +#780734 by c960657: Clean up node_comment_form plugin's form_comment_form_alter() implementation. +Fix user_view task to use variable instead of value on hook invocation to avoid warnings on PHP5.3 +#771132: Move object cache system over to ctools_static() and introduce static var resets when locks are cleared. +#762996 by jonskulski: Allow views_content panes to selectively show/hide their view's fields. +#789524 by c960657: Implement "content type" hook on block content_type plugin. +#782070: Relationship form submits were being passed an invalid part of $form_state. +#767952 by aosodoev: Fix ctools_css_assemble() burping on multiple selectors by switching in str_replace() for preg_replace(). +#489256 by dww: Add a content_type plugin for outputting taxonomy terms from a node context. +Assorted XSS, XSRF, and information disclosure security fixes. + +ctools 6.x-1.3 (2010-Feb-01) +============== +Added support for context keyword substitutions on override paths in content panes provided by views_content. +#612850: Fix crash bug with panes referencing deleted/missing views. +#595442: Fix AJAX problems with mod_security enabled. +Introduce a "jump menu" tool which can be used to provide jump menus with a select. +Change plugins to no longer need magic function. Can now use $plugin = array(...) instead. +#652236 by alevine: Preserve pre-existing class when adding ajax functionality to form widgets. +#657474: Allows clean exporting for task handlers set to be the homepage. +#588246 by brynbellomy: Add "context exists" access plugin. +#618194 by brynbellomy: Add "string length" access plugin. +#618204 by brynbellomy: Add "string comparison" access plugin. +#621444 by hefox: contact pages should only show up if contact module is active. +#649144 by neclimdul: Expand ctools_include() to work for other modules. Move API version to 1.3.1 +#646944 by DamienMcKenna: Fix wrong variable name in page_manager_enable_page(). +Allow "admin path" to be empty for tasks to support Panels Everywhere. +Introduce 'export callback' to individual fields in export.inc. Add some documentation to export.html -- much of it borrowed from stella! +#686826 by dagmar: Improve AJAX error notifications. +#625696 by dmmckenna: Bulk exporter did not define empty array at beginning in code it creates for you. +#651852 by coreyp_1: Add caching to content subtypes to save some queries. This means developers will need to clear caches when changing content type code. +#630982 by Roi Danton: Dependent javascript failed to work properly if radios being depended on had no value at all. +#661332 by yhahn: Allow export.inc to export stdClass objects by exporting them as an array and casting them to an object. +#654218 by Roi Danton: Improve documentation of dependent.inc to talk about annoyances with checkboxes, radios and fieldsets. +#538092: Add converters to the node edit form context so node fields can be available. +#484340: Support for token module in the context keywords. +#662242: Page Manager was not removing menu items when pages were deleted due to caching. +#639548: export.inc cache was not properly respected when loading individual items, leading to multiple redundant queries. +#573646: Attempt to make sure page manager does not try to respond to menu/theme hooks when CTools is not enabled. +#544438: Extend user context to allow selection of user, including "logged in user". +#604976: Prevent Page Manager from throwing errors when no modules that provide variants are available. +Add 'Update and save' button to reduce the number of needed steps to do basic content editing. +#693742: Sanitize block admin output (to Panels drag & drop for example) to get rid of script tags. + +ctools 6.x-1.2 (2009-Oct-21) +============== +#605990 by johnskulski: Prevent Views PHP error if display was removed. +#605968 by johnskulski: Show more information in the collapsible for Views Panes. +#609024: Fix improper validation of views introduced in #547686. + +ctools 6.x-1.1 (2009-Oct-15) +============== + +Fix problem with ctools_set_page_token() +Add a couple of support functions for ctools_set_page_token that are meant to be used by themes. +#563916 by Damien Tournoud: ajax before() operation not using behaviors correctly. +#553112: dependent.js failed to set proper initial state if inside an already hidden element. +#569508 by markus_petrux: Update user_profile content type. +#558942 by Roi Danton: In wizard.inc, be sure to check cancel path if return path is not set, as noted in documentation. +#568578 by Roger Lopez: Add client side redirect AJAX command. +#561788 by sirkitree: Add client side reload AJAX command. +#566256 by mikl: HTML safe converter for string context. +#558856 by sdboyer: Allow Views Panes to mark contexts optional. +#558902 by Roi Danton: Better documentation of how to handle the back button with wizard.inc. +#565808 by sirkitree: Replace /nojs/g instead of just "/nojs/" with ajax, allowing nojs to be the last item in a URL. +#564522 by Roger Lopez: Prevent accidental inclusion of .info files in plugins. +#558918: Collapsible can be set to remember state between page loads. Allow collapsible handle and content to be separated and not have to be divs. +#545208: Page cache needs to be cleared when page manager pages are saved. +#577542 by EclipseGC: Add footer message as a page element. +#581670: Fix autocomplete in the modal so that using it does not submit the form. +#580342: Fix Page Manager variant import, which did not work at all. +#589342: Introduce page_manager_get_current_page() to get information about the current page manager page. +#564492: by Roger Lopez: Change default class includes from .inc files to .class.php files so they don't get read as plugins. +#590654 by fenstrat: Add submit form as a possible AJAX operation. +#534034 by DamienMcKenna: Add access rule for term ID selection. +#531522 by alex_b: Introduce ctools_static() modelled after static object handling in D7. +#541428 by viz8: User name as a context argument. +#592692 by johnskulski: use theme_links instead of theme('links') for dropdown because we do not actually want a theme to change this output. +#547686: Allow view panes to better respect the default pager settings. +#424548: Add a warning about overridng pager settings with Views AJAX. +#555802: Add an administrative title to custom content panes to make them easier to manage. +#556870: Node edit settings form context autocomplete was not working correctly. +#491884 by ayalon: Provide blank substitutions for optional contexts that do not appear. +#599136 by alex_b: Fix incorrect references to object unique name in export.inc. +Allow the string argument to accept the entire path tail. +#578410: Search path override, plus search form and search result content types. +#567778: Allow override of contact and user contact pages. +Allow override of blog and user blog pages. +Allow override of poll page. +#596450 by Scott Reynolds: Provide an ajax command response to reset the modal to the 'loading' state. +#554678: Do not allow % or ! by itself as part of a path, as that breaks arguments. +#599428: Enable and Disable variant buttons led to "Operation trail does not exist." +Show a LOCK icon on the page list when pages are locked for editing either by the current user or another user. + +ctools 6.x-1.0 (2009-Aug-19) +============== + +#534570: Fix _ and - not recognized in for context keywords. +#535744 by Senpai: Rename "post" to "node" in various nid selectors. +Make sure that tasks that will not override existing overrides refuse to enable and provide an error message saying why. +#540750 by manuee: User picture was not available despite having a .inc file. +#537184 by stephthegeek: CSS tweaks to fix heights on operations. +#471024: Stop preventing exposed-view-in-block blocks from showing up as content panes. +#483170: Link paths in page list if they have sensible destinations. +#406284: Allow items with the user uid argument to be used as a normal menu item. +#534504: Selection rules were not being saved when set up via during variant add. +#528392 by markus_petrux: Explicit NOT NULL settings in schema during install. +#348323 by neclimdul: Allow plugins to have classes and auto build parent chains. +#478542 by nickl: Add "attr" command to ajax framework. +#495240 by mikl: Blob handling for pgsql. +#531936: Cache handling on contexts was spotty and could cause random errors. +#545540 by Roger López: Add 5 page elements as available panes for using Panels as your primary page layout: breadcrumb, page title, messages, tabs and help box. +#537776 by rfay: CTools Plugin Example module to help guide people in making plugins. +#552020: Show the administrative description on page manager edit forms. +#549380 by Nick Lewis: DX improvements to the multistep wizard. + +ctools 6.x-1.0-rc1 +================== + +#510968: Arguments needed to be recalulculated when path changed in page task. +#522454 by stella: export.inc not properly using the 'key' instead of 'name' everywhere. +#132557: Allow alter hook for rendered data: hook_ctools_render_alter() +#520128: Context object may not be available when loading page cache. +#498066 by mikl: Fix class names in advanced help. +#504286 by Darren Oh: Set proper primary key on ctools_object_cache +#514432 by markus_petrux: Various node fields available as a pane. +#451928 by populist: Fix file upload from modals. +#522836 by andrewlevine: Add form_clean_id() to ctools_rebuild_form() to prevent extraneous -1s from appearing. +#518254: Accidentally inverted truth value on compare users. +#464252 by andrewlevine: Helper to make onchange AJAX requests for select boxes. +#490672 by dereine: Title overrides not working for system block using custom block. +#520402: Disabled some concept code for later use that apparently conflicts with admin_menu. +#523712: Fix call-time pass by reference typo. +#477334 by dkruglyak: Remove forced lowercase on CSS processing. +#484340: Allow keyword substitution in custom content. +#458300: Option to inherit panel path on views panes not being properly honored. +#493620: Add a PHP Code option to access control. +#516222: Use "DELETE FROM" instead of "TRUNCATE" which is not supported by SQLite. +#444456: Add Node: Node type as a context converter for substitutions and views arguments. +#516504: Make sure optional contexts are truly and completely optional. +#528022 by tha_sun: Change wording of "Add variant" to "Create variant" to avoid confusion with the "Add variant" tab. +#528066: Required context (used by Mini Panels) accidentally had "weight" when not needed. + +ctools 6.x-1.0-beta4 +================== +#451078: Fix silly typo preventing contexts from getting to views. Again. +#457376: Text fields need array defaults. This only broke in pgsql. +Add a hook to allow other modules to cooperate a bit more easily with node page overriding. +#472222: Prevent modules providing invalid user data from causing warnings in profile content. +#478438 by nickl: Allow passing items to the data() element. +#480252 Fix some PHP notices. +#447064 by nickl: Improve requirements message when css cache directory cannot be created. +#481928: Needed indexes on delegator handlers and pages tables. +#484284 by crea: Add a node links content type to print just a node's links. +#485486 by nrambeck: term view override was not setting breadcrumb like taxonomy/term is supposed to. +#498000: Allow .info files to create data for plugins. +Fix a bug in plugins.inc where if two modules create a plugin of the same +name, they would accidentally share data. +#512048: by tom_o_t: Path fallback override callback had bad logic. + +IMPORTANT: +Removed the delegator module entirely. There is now a page_manager module in +its place, with a vastly improved workflow and user interface. Activating it +should automatically update your data to the new module. However, PLEASE +PLEASE PLEASE back up your data before using it. Just enough changed to make +this a bit of a concern. + +#514468 by hippich: Fix typos in content.menu.inc related to db_rewrite_sql() use. +#508292 by rfay: Add user comparison access plugin. +API version bumped to 1.1.0 to reflect the death of delegator. +by sdboyer: Bulk Export module created to replace Panels bulk export. + +ctools 6.x-1.0-beta3 +================== +#459716: content.theme.inc missing typo caused PHP error. +#455732 by dereine: Restore code to pull the title from the blocks table for block types. +#451928 by josh_k: Allow file uploads in the modal. +#447920: Ensure there is a context selector for the "terms" argument and context converters so it can be used with Views. +#458300: Panels not using proper method to override the path for the view. +Add edit tabs to pages. Up API version to 1.0.1 diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/LICENSE.txt b/drupal/sites/default/boinc/modules/contrib/ctools/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..d159169d1050894d3ea3b98e1c965c4058208fe1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.css b/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.css new file mode 100644 index 0000000000000000000000000000000000000000..41b0592bdbda6d82e79b9a97fb962240696e70ee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.css @@ -0,0 +1,17 @@ + +div.export-container { + width: 48%; + float: left; + padding: .5em; +} + +div.export-container table { + width: 100%; +} + +div.export-container table input, +div.export-container table th, +div.export-container table td { + padding: 0 0 0 .5em; + margin: 0; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.info b/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.info new file mode 100644 index 0000000000000000000000000000000000000000..7ec7057c66653ff8949811efd640bdaaeb4f95e2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.info @@ -0,0 +1,11 @@ +name = Bulk Export +description = Performs bulk exporting of data objects known about by Chaos tools. +core = 6.x +dependencies[] = ctools +package = Chaos tool suite +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.module b/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.module new file mode 100644 index 0000000000000000000000000000000000000000..95412afa453e0ee65e67fb70780fd6e83bf8a714 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/bulk_export/bulk_export.module @@ -0,0 +1,224 @@ +<?php +/** + * @file + * Perform bulk exports. + */ + +/** + * Implements hook_perm(). + */ +function bulk_export_perm() { + return array('use bulk exporter'); +} + +/** + * Implements hook_theme(). + */ +function bulk_export_theme() { + return array('bulk_export_export_form' => array( + 'arguments' => array('form' => NULL), + ), + ); +} + +/** + * Implements hook_menu(). + */ +function bulk_export_menu() { + $items['admin/build/bulkexport'] = array( + 'title' => 'Bulk Exporter', + 'description' => 'Bulk-export multiple CTools-handled data objects to code.', + 'access arguments' => array('use bulk exporter'), + 'page callback' => 'bulk_export_export', + ); + $items['admin/build/bulkexport/results'] = array( + 'access arguments' => array('use bulk exporter'), + 'page callback' => 'bulk_export_export', + 'type' => MENU_CALLBACK, + ); + return $items; +} + +/** + * FAPI gateway to the bulk exporter. + */ +function bulk_export_export() { + ctools_include('export'); + $schemas = ctools_export_get_schemas(TRUE); + $exportables = $export_tables = array(); + + foreach ($schemas as $table => $schema) { + if (!empty($schema['export']['list callback']) && function_exists($schema['export']['list callback'])) { + $exportables[$table] = $schema['export']['list callback'](); + } + else { + $exportables[$table] = ctools_export_default_list($table, $schema); + } + natcasesort($exportables[$table]); + $export_tables[$table] = $schema['module']; + } + if ($exportables) { + ctools_include('form'); + $form_state = array( + 're_render' => FALSE, + 'no_redirect' => TRUE, + 'exportables' => $exportables, + 'export_tables' => $export_tables, + ); + $output = ctools_build_form('bulk_export_export_form', $form_state); + if (!$output) { + drupal_set_title(t('Bulk export results')); + $output = ''; + $module_code = ''; + $api_code = ''; + $dependencies = array(); + foreach ($form_state['code'] as $module => $api_info) { + if ($module == 'general') { + $module_code .= $api_info; + } + else { + foreach ($api_info as $api => $info) { + $api_code .= " if (\$module == '$module' && \$api == '$api') {\n"; + $api_code .= " return array('version' => $info[version]);\n"; + $api_code .= " }\n"; + $dependencies[$module] = TRUE; + + $file = $form_state['module'] . '.' . $api . '.inc'; + $code = "<?php\n"; + $code .= "/**\n"; + $code .= " * @file\n"; + $code .= " * Bulk export of $api objects generated by Bulk export module.\n"; + $code .= " */\n\n"; + $code .= $info['code']; + $output .= drupal_get_form('ctools_export_form', $code, t('Place this in @file', array('@file' => $file))); + } + } + } + + // Add hook_ctools_plugin_api at the top of the module code, if there is any. + if ($api_code) { + $api = "/**\n"; + $api .= " * Implements hook_ctools_plugin_api().\n"; + $api .= " */\n"; + $api .= "function $form_state[module]_ctools_plugin_api(\$module, \$api) {\n"; + $api .= $api_code; + $api .= "}\n"; + $module_code = $api . $module_code; + } + + if ($module_code) { + $module = "<?php\n"; + $module .= "/**\n"; + $module .= " * @file\n"; + $module .= " * Bulk export of objects generated by Bulk export module.\n"; + $module .= " */\n\n"; + $module .= $module_code; + $output = drupal_get_form('ctools_export_form', $module, t('Place this in @file', array('@file' => $form_state['module'] . '.module'))) . $output; + } + + $info = strtr("name = @module export module\n", array('@module' => $form_state['module'])); + $info .= strtr("description = Export objects from CTools\n", array('@module' => $form_state['values']['name'])); + foreach ($dependencies as $module => $junk) { + $info .= "dependencies[] = $module\n"; + } + $info .= "package = Chaos tool suite\n"; + $info .= "core = 6.x\n"; + $output = drupal_get_form('ctools_export_form', $info, t('Place this in @file', array('@file' => $form_state['module'] . '.info'))) . $output; + + } + return $output; + } + else { + return t('There are no objects to be exported at this time.'); + } +} + +/** + * FAPI definition for the bulk exporter form. + * + */ +function bulk_export_export_form(&$form_state) { + $form = array(); + $form['tables'] = array( + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + + foreach ($form_state['exportables'] as $table => $list) { + $form['tables'][$table] = array( + '#type' => 'checkboxes', + '#options' => $list, + '#default_value' => array(), + ); + } + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Module name'), + '#description' => t('Enter the module name to export code to.'), + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Export'), + ); + + $form['#action'] = url('admin/build/bulkexport/results'); + $form['#exportables'] = $form_state['exportables']; + $form['#export_tables'] = $form_state['export_tables']; + return $form; +} + +/** + * Display the bulk export form. + */ +function theme_bulk_export_export_form($form) { + $files = module_rebuild_cache(); + $exportables = $form['#exportables']; + $export_tables = $form['#export_tables']; + $output = ''; + + foreach ($export_tables as $table => $module) { + $header = array(theme('table_select_header_cell'), "{$files[$module]->info['name']}: $table"); + $rows = array(); + foreach ($exportables[$table] as $name => $title) { + // $title = $form['tables'][$table][$name]['#title']; + unset($form['tables'][$table][$name]['#title']); + $rows[] = array(drupal_render($form['tables'][$table][$name]), $title); + } + + if ($rows) { + $output .= '<div class="export-container">'; + $output .= theme('table', $header, $rows); + $output .= "</div>\n"; + } + } + + if (empty($output)) { + $output = t('There are no objects in your system that may be exported at this time.'); + } + + drupal_add_css(drupal_get_path('module', 'bulk_export') . '/bulk_export.css'); + $output .= drupal_render($form); + return $output; +} + +/** + * Process the bulk export submit form and make the results available. + */ +function bulk_export_export_form_submit($form, &$form_state) { + $code = array(); + $name = empty($form_state['values']['name']) ? 'foo' : $form_state['values']['name']; + + foreach ($form_state['values']['tables'] as $table => $names) { + $names = array_keys(array_filter($names)); + if ($names) { + natcasesort($names); + ctools_export_to_hook_code($code, $table, $names, $name); + } + } + + $form_state['code'] = $code; + $form_state['module'] = $name; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/collapsible-div.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/collapsible-div.css new file mode 100644 index 0000000000000000000000000000000000000000..91e787691e53495590569abe7f06744929232084 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/collapsible-div.css @@ -0,0 +1,18 @@ + +.ctools-collapsible-container .ctools-toggle { + float: left; + width: 21px; + height: 21px; + cursor: pointer; + background-position: 7px 7px; + background-repeat: no-repeat; + background-image: url(../images/collapsible-expanded.png); +} + +.ctools-collapsible-container .ctools-collapsible-handle { + cursor: pointer; +} + +.ctools-collapsible-container .ctools-toggle-collapsed { + background-image: url(../images/collapsible-collapsed.png); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/context.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/context.css new file mode 100644 index 0000000000000000000000000000000000000000..5093104c83abc1670f2f1246adbaffe6047d5f21 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/context.css @@ -0,0 +1,10 @@ +.ctools-context-holder .ctools-context-title { + float: left; + width: 49%; + font-style: italic; +} + +.ctools-context-holder .ctools-context-content { + float: right; + width: 49%; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/ctools.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/ctools.css new file mode 100644 index 0000000000000000000000000000000000000000..7372988df8a07c921a717b57c5e26bb27618f817 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/ctools.css @@ -0,0 +1,25 @@ +.ctools-locked { + color: red; + border: 1px solid red; + padding: 1em; +} + +.ctools-owns-lock { + background: #FFFFDD none repeat scroll 0 0; + border: 1px solid #F0C020; + padding: 1em; +} + +a.ctools-ajaxing, +input.ctools-ajaxing, +button.ctools-ajaxing, +select.ctools-ajaxing { + padding-right: 18px !important; + background: url(../images/status-active.gif) right center no-repeat; +} + +div.ctools-ajaxing { + float: left; + width: 18px; + background: url(../images/status-active.gif) center center no-repeat; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/dropdown.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/dropdown.css new file mode 100644 index 0000000000000000000000000000000000000000..9d94d07f749037d888367688591a9b4d3df30d14 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/dropdown.css @@ -0,0 +1,71 @@ +html.js div.ctools-dropdown div.ctools-dropdown-container { + z-index: 1001; + display: none; + text-align: left; + position: absolute; +} + +html.js div.ctools-dropdown div.ctools-dropdown-container ul li a { + display: block; +} + +html.js div.ctools-dropdown div.ctools-dropdown-container ul { + list-style-type: none; +} + +html.js div.ctools-dropdown div.ctools-dropdown-container ul li { + display: block; + /* prevent excess right margin in IE */ + margin-right: 0; + margin-left: 0; + padding-right: 0; + padding-left: 0; + background-image: none; /* prevent list backgrounds from mucking things up */ +} + +.ctools-dropdown-no-js .ctools-dropdown-link, +.ctools-dropdown-no-js span.text { + display: none; +} + +/* Everything from here down is purely visual style and can be overridden. */ + +html.js div.ctools-dropdown a.ctools-dropdown-text-link { + background: url(../images/collapsible-expanded.png) 3px 5px no-repeat; + padding-left: 12px; +} + +html.js div.ctools-dropdown div.ctools-dropdown-container { + width: 175px; + background: #fff; + border: 1px solid black; + margin: 4px 1px 0 0; + padding: 0; + color: #494949; +} + +html.js div.ctools-dropdown div.ctools-dropdown-container ul li li a { + padding-left: 25px; + width: 150px; + color: #027AC6; +} + +html.js div.ctools-dropdown div.ctools-dropdown-container ul li a { + text-decoration: none; + padding-left: 5px; + width: 170px; + color: #027AC6; +} + +html.js div.ctools-dropdown div.ctools-dropdown-container ul li span { + display: block; +} + +html.js div.ctools-dropdown div.ctools-dropdown-container ul li span.text { + font-style: italic; + padding-left: 5px; +} + +html.js .ctools-dropdown-hover { + background-color: #ECECEC; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/export-ui-list.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/export-ui-list.css new file mode 100644 index 0000000000000000000000000000000000000000..a16b8054fb66a082e26fe3114fab7daf378aeb8e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/export-ui-list.css @@ -0,0 +1,32 @@ +body form#ctools-export-ui-list-form { + margin: 0 0 20px 0; +} + +#ctools-export-ui-list-form .form-item { + padding-right: 1em; /* LTR */ + float: left; /* LTR */ + margin-top: 0; + margin-bottom: 0; +} + +#ctools-export-ui-list-items { + width: 100%; +} + +#edit-order-wrapper { + clear: left; /* LTR */ +} + +#ctools-export-ui-list-form .form-submit { + margin-top: 1.65em; + float: left; /* LTR */ +} + +tr.ctools-export-ui-disabled { + color: #999; +} + +th.ctools-export-ui-operations, +td.ctools-export-ui-operations { + text-align: right; /* LTR */ +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/modal.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/modal.css new file mode 100644 index 0000000000000000000000000000000000000000..90389b9eb67bef4e7fd9974239e84b35eec627b7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/modal.css @@ -0,0 +1,105 @@ +div.ctools-modal-content { + background: #fff; + color: #000; + padding: 0; + margin: 2px; + border: 1px solid #000; + width: 600px; + text-align: left; +} + +div.ctools-modal-content .modal-title { + font-size: 120%; + font-weight: bold; + color: white; + overflow: hidden; + white-space: nowrap; +} + +div.ctools-modal-content .modal-header { + background-color: #2385c2; + padding: 0 .25em 0 1em; +} + +div.ctools-modal-content .modal-header a { + color: white; + float: right; +} + +div.ctools-modal-content .modal-content { + padding: 1em 1em 0 1em; + overflow: auto; + position: relative; /* Keeps IE7 from flowing outside the modal. */ +} + +div.ctools-modal-content .modal-form { +} + +div.ctools-modal-content a.close { + color: white; +} + +div.ctools-modal-content a.close:hover { + text-decoration: none; +} + +div.ctools-modal-content a.close img { + position: relative; + top: 1px; +} + +div.ctools-modal-content .modal-content .modal-throbber-wrapper { + text-align: center; +} + +div.ctools-modal-content .modal-content .modal-throbber-wrapper img { + margin-top: 160px; +} + +/** modal forms CSS **/ +div.ctools-modal-content .form-item label { + width: 15em; + float: left; +} + +div.ctools-modal-content .form-item label.option { + width: auto; + float: none; +} + +div.ctools-modal-content .form-item .description { + clear: left; +} + +div.ctools-modal-content .form-item .description .tips { + margin-left: 2em; +} + +div.ctools-modal-content .no-float .form-item * { + float: none; +} + +div.ctools-modal-content .modal-form .no-float label { + width: auto; +} + +div.ctools-modal-content fieldset, +div.ctools-modal-content .form-radios, +div.ctools-modal-content .form-checkboxes { + clear: left; +} + +div.ctools-modal-content .resizable-textarea { + width: auto; + margin-left: 15em; + margin-right: 5em; +} + +div.ctools-modal-content .container-inline .form-item { + margin-right: 2em; +} + +#views-exposed-pane-wrapper .form-item { + margin-top: 0; + margin-bottom: 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/ruleset.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/ruleset.css new file mode 100644 index 0000000000000000000000000000000000000000..891455f019994aeb4732a2b20a5c517929e93a2d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/ruleset.css @@ -0,0 +1,11 @@ +.ctools-right-container { + float: right; + padding: 0 0 0 .5em; + margin: 0; + width: 48.5%; +} + +.ctools-left-container { + padding-right: .5em; + width: 48.5%; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/stylizer.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/stylizer.css new file mode 100644 index 0000000000000000000000000000000000000000..a16ec789bfd960ab98508bb59cb6f62ac899fd1a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/stylizer.css @@ -0,0 +1,129 @@ + +/* Farbtastic placement */ +.color-form { + max-width: 50em; + position: relative; + min-height: 195px; +} +#placeholder { +/* + position: absolute; + top: 0; + right: 0; +*/ + margin: 0 auto; + width: 195px; +} + +/* Palette */ +.color-form .form-item { + height: 2em; + line-height: 2em; + padding-left: 1em; /* LTR */ + margin: 0.5em 0; +} + +.color-form .form-item input { + margin-top: .2em; +} + +.color-form label { + float: left; /* LTR */ + clear: left; /* LTR */ + width: 14em; +} +.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 .up { + background-position: 100% -27px; /* LTR */ +} +#palette .both { + background-position: 100% -54px; /* LTR */ +} + + +#palette .form-item { + width: 24em; +} +#palette .item-selected { + background: #eee; +} + +/* Preview */ +#preview { + width: 45%; + float: right; + margin: 0; +} + +#ctools_stylizer_color_scheme_form { + float: left; + width: 45%; + margin: 0; +} + +/* general style for the layout-icon */ +.ctools-style-icon .caption { + width: 100px; + margin-bottom: 1em; + line-height: 1em; + text-align: center; + cursor: default; +} + +.ctools-style-icons .form-item { + width: 100px; + float: left; + margin: 0 3px !important; +} + +.ctools-style-icons .form-item .ctools-style-icon { + float: none; + height: 150px; + width: 100px; +} + +.ctools-style-icons .form-item label.option { + width: 100px; + display: block; + text-align: center; +} + +.ctools-style-icons .form-item label.option input { + margin: 0 auto; +} + +.ctools-style-icons .ctools-style-category { + height: 190px; +} + +.ctools-style-icons .ctools-style-category label { + font-weight: bold; + width: 100%; + float: left; +} + +/** + * Stylizer font editor widget + */ +.ctools-stylizer-spacing-form .form-item { + float: left; + margin: .25em; +} + +#edit-font-font { + width: 9em; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/css/wizard.css b/drupal/sites/default/boinc/modules/contrib/ctools/css/wizard.css new file mode 100644 index 0000000000000000000000000000000000000000..d42a2db061239c11c160cb07196124c3065151d3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/css/wizard.css @@ -0,0 +1,8 @@ + +.wizard-trail { + font-size: 120%; +} + +.wizard-trail-current { + font-weight: bold; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools.api.php b/drupal/sites/default/boinc/modules/contrib/ctools/ctools.api.php new file mode 100644 index 0000000000000000000000000000000000000000..fd2cd827b787d169578b4a9b6aabaeec3b2633c0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools.api.php @@ -0,0 +1,100 @@ +<?php + +/** + * @file + * Hooks provided by the Chaos Tool Suite. + * + * This file is divided into static hooks (hooks with string literal names) and + * dynamic hooks (hooks with pattern-derived string names). + */ + +/** + * @addtogroup hooks + * @{ + */ + +/** + * This hook is used to inform the CTools plugin system about the location of a + * directory that should be searched for files containing plugins of a + * particular type. CTools invokes this same hook for all plugins, using the + * two passed parameters to indicate the specific type of plugin for which it + * is searching. + * + * The $plugin_type parameter is self-explanatory - it is the string name of the + * plugin type (e.g., Panels' 'layouts' or 'styles'). The $owner parameter is + * necessary because CTools internally namespaces plugins by the module that + * owns them. This is an extension of Drupal best practices on avoiding global + * namespace pollution by prepending your module name to all its functions. + * Consequently, it is possible for two different modules to create a plugin + * type with exactly the same name and have them operate in harmony. In fact, + * this system renders it impossible for modules to encroach on other modules' + * plugin namespaces. + * + * Given this namespacing, it is important that implementations of this hook + * check BOTH the $owner and $plugin_type parameters before returning a path. + * If your module does not implement plugins for the requested module/plugin + * combination, it is safe to return nothing at all (or NULL). As a convenience, + * it is also safe to return a path that does not exist for plugins your module + * does not implement - see form 2 for a use case. + * + * Note that modules implementing a plugin also must implement this hook to + * instruct CTools as to the location of the plugins. See form 3 for a use case. + * + * The conventional structure to return is "plugins/$plugin_type" - that is, a + * 'plugins' subdirectory in your main module directory, with individual + * directories contained therein named for the plugin type they contain. + * + * @param string $owner + * The system name of the module owning the plugin type for which a base + * directory location is being requested. + * @param string $plugin_type + * The name of the plugin type for which a base directory is being requested. + * @return string + * The path where CTools' plugin system should search for plugin files, + * relative to your module's root. Omit leading and trailing slashes. + */ +function hook_ctools_plugin_directory($owner, $plugin_type) { + // Form 1 - for a module implementing only the 'content_types' plugin owned + // by CTools, this would cause the plugin system to search the + // <moduleroot>/plugins/content_types directory for .inc plugin files. + if ($owner == 'ctools' && $plugin_type == 'content_types') { + return 'plugins/content_types'; + } + + // Form 2 - if your module implements only Panels plugins, and has 'layouts' + // and 'styles' plugins but no 'cache' or 'display_renderers', it is OK to be + // lazy and return a directory for a plugin you don't actually implement (so + // long as that directory doesn't exist). This lets you avoid ugly in_array() + // logic in your conditional, and also makes it easy to add plugins of those + // types later without having to change this hook implementation. + if ($owner == 'panels') { + return "plugins/$plugin_type"; + } + + // Form 3 - CTools makes no assumptions about where your plugins are located, + // so you still have to implement this hook even for plugins created by your + // own module. + if ($owner == 'mymodule') { + // Yes, this is exactly like Form 2 - just a different reasoning for it. + return "plugins/$plugin_type"; + } + // Finally, if nothing matches, it's safe to return nothing at all (or NULL). +} + +/** + * Alter the available functions to be used in ctools math expression api. + * + * One usecase would be to create your own function in your module and + * allow to use it in the math expression api. + * + * @param $functions + * An array which has the functions as value. + */ +function hook_ctools_math_expression_functions_alter(&$functions) { + // Allow to convert from degrees to radiant. + $functions[] = 'deg2rad'; +} + +/** + * @} End of "addtogroup hooks". + */ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools.info b/drupal/sites/default/boinc/modules/contrib/ctools/ctools.info new file mode 100644 index 0000000000000000000000000000000000000000..bed3bc41355e7bfb3dda3a98e3c3c968d27b2b00 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools.info @@ -0,0 +1,10 @@ +name = Chaos tools +description = A library of helpful tools by Merlin of Chaos. +core = 6.x +package = Chaos tool suite +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools.install b/drupal/sites/default/boinc/modules/contrib/ctools/ctools.install new file mode 100644 index 0000000000000000000000000000000000000000..178af49ff6fe007523223c21459c8abaea7d0e07 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools.install @@ -0,0 +1,231 @@ +<?php + +/** + * @file + * Contains install and update functions for ctools. + */ + +/** + * Use requirements to ensure that the CTools CSS cache directory can be + * created and that the PHP version requirement is met. + */ +function ctools_requirements($phase) { + $requirements = array(); + if ($phase == 'runtime') { + $path = file_create_path('ctools/css'); + if (!file_check_directory($path)) { + $path = file_directory_path() . '/ctools'; + file_check_directory($path, FILE_CREATE_DIRECTORY); + $path .= '/css'; + file_check_directory($path, FILE_CREATE_DIRECTORY); + } + + $requirements['ctools_css_cache'] = array( + 'title' => t('CTools CSS Cache'), + 'severity' => REQUIREMENT_OK, + 'value' => t('Exists'), + ); + + if (!file_check_directory($path)) { + $requirements['ctools_css_cache']['description'] = t('The CTools CSS cache directory, %path could not be created due to a misconfigured files directory. Please ensure that the files directory is correctly configured and that the webserver has permission to create directories.', array('%path' => $path)); + $requirements['ctools_css_cache']['severity'] = REQUIREMENT_ERROR; + $requirements['ctools_css_cache']['value'] = t('Unable to create'); + } + + if (!function_exists('error_get_last')) { + $requirements['ctools_php_52']['title'] = t('CTools PHP requirements'); + $requirements['ctools_php_52']['description'] = t('CTools requires certain features only available in PHP 5.2.0 or higher.'); + $requirements['ctools_php_52']['severity'] = REQUIREMENT_WARNING; + $requirements['ctools_php_52']['value'] = t('PHP !version', array('!version' => phpversion())); + } + } + + return $requirements; +} + +/** + * Implementation of hook_install() + */ +function ctools_install() { + drupal_install_schema('ctools'); +} + +/** + * Implementation of hook_uninstall() + */ +function ctools_uninstall() { + drupal_uninstall_schema('ctools'); +} + +/** + * Implementation of hook_schemea + */ +function ctools_schema() { + return ctools_schema_2(); +} + +/** + * Version 2 of the CTools schema. + */ +function ctools_schema_2() { + $schema = ctools_schema_1(); + + // update the 'name' field to be 128 bytes long: + $schema['ctools_object_cache']['fields']['name']['length'] = 128; + + // DO NOT MODIFY THIS TABLE -- this definition is used to create the table. + // Changes to this table must be made in schema_3 or higher. + $schema['ctools_css_cache'] = array( + 'description' => 'A special cache used to store CSS that must be non-volatile.', + 'fields' => array( + 'cid' => array( + 'type' => 'varchar', + 'length' => '128', + 'description' => 'The CSS ID this cache object belongs to.', + 'not null' => TRUE, + ), + 'filename' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'The filename this CSS is stored in.', + ), + 'css' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'CSS being stored.', + 'serialize' => TRUE, + ), + 'filter' => array( + 'type' => 'int', + 'size' => 'tiny', + 'description' => 'Whether or not this CSS needs to be filtered.', + ), + ), + 'primary key' => array('cid'), + ); + + return $schema; +} + +/** + * CTools' initial schema; separated for the purposes of updates. + * + * DO NOT MAKE CHANGES HERE. This schema version is locked. + */ +function ctools_schema_1() { + $schema['ctools_object_cache'] = array( + 'description' => t('A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment.'), + 'fields' => array( + 'sid' => array( + 'type' => 'varchar', + 'length' => '64', + 'not null' => TRUE, + 'description' => 'The session ID this cache object belongs to.', + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '32', + 'not null' => TRUE, + 'description' => 'The name of the object this cache is attached to.', + ), + 'obj' => array( + 'type' => 'varchar', + 'length' => '32', + 'not null' => TRUE, + 'description' => 'The type of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache.', + ), + 'updated' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The time this cache was created or updated.', + ), + 'data' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Serialized data being stored.', + 'serialize' => TRUE, + ), + ), + 'primary key' => array('sid', 'obj', 'name'), + 'indexes' => array('updated' => array('updated')), + ); + return $schema; +} + +/** + * Enlarge the ctools_object_cache.name column to prevent truncation and weird + * errors. + */ +function ctools_update_6001() { + $ret = array(); + + // Perform updates like this to reduce code duplication. + $schema = ctools_schema_2(); + + db_change_field($ret, 'ctools_object_cache', 'name', 'name', $schema['ctools_object_cache']['fields']['name']); + + return $ret; +} + +/** + * Add the new css cache table. + */ +function ctools_update_6002() { + $ret = array(); + + // Schema 2 is locked and should not be changed. + $schema = ctools_schema_2(); + + db_create_table($ret, 'ctools_css_cache', $schema['ctools_css_cache']); + return $ret; +} + +/** + * Take over for the panels_views module if it was on. + */ +function ctools_update_6003() { + $ret = array(); + + $result = db_result(db_query("SELECT status FROM {system} WHERE name = 'panels_views'")); + if ($result) { + $ret[] = update_sql("DELETE from {system} WHERE name = 'panels_views'"); + drupal_install_modules(array('views_content')); + } + + return $ret; +} + +/** + * Add primary key to the ctools_object_cache table. + */ +function ctools_update_6004() { + $ret = array(); + db_add_primary_key($ret, 'ctools_object_cache', array('sid', 'obj', 'name')); + db_drop_index($ret, 'ctools_object_cache', 'sid_obj_name'); + return $ret; +} + +/** + * Removed update. + */ +function ctools_update_6005() { + return array(); +} + +/** + * ctools_custom_content table was originally here, but is now moved to + * its own module. + */ +function ctools_update_6007() { + $ret = array(); + if (db_table_exists('ctools_custom_content')) { + // Enable the module to make everything as seamless as possible. + drupal_install_modules(array('ctools_custom_content')); + } + + return $ret; +} + + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools.module b/drupal/sites/default/boinc/modules/contrib/ctools/ctools.module new file mode 100644 index 0000000000000000000000000000000000000000..7862c005cc7aedd41609c43502c8d33e53361dd1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools.module @@ -0,0 +1,799 @@ +<?php + +/** + * @file + * CTools primary module file. + * + * Most of the CTools tools are in their own .inc files. This contains + * nothing more than a few convenience functions and some hooks that + * must be implemented in the module file. + */ + +define('CTOOLS_API_VERSION', '1.9'); + +/** + * Test the CTools API version. + * + * This function can always be used to safely test if CTools has the minimum + * API version that your module can use. It can also try to protect you from + * running if the CTools API version is too new, but if you do that you need + * to be very quick about watching CTools API releases and release new versions + * of your software as soon as the new release is made, or people might end up + * updating CTools and having your module shut down without any recourse. + * + * It is recommended that every hook of your module that might use CTools or + * might lead to a use of CTools be guarded like this: + * + * @code + * if (!module_invoke('ctools', 'api_version', '1.0')) { + * return; + * } + * @endcode + * + * Note that some hooks such as _menu() or _theme() must return an array(). + * + * You can use it in your hook_requirements to report this error condition + * like this: + * + * @code + * define('MODULENAME_MINIMUM_CTOOLS_API_VERSION', '1.0'); + * define('MODULENAME_MAXIMUM_CTOOLS_API_VERSION', '1.1'); + * + * function MODULENAME_requirements($phase) { + * $requirements = array(); + * if (!module_invoke('ctools', 'api_version', MODULENAME_MINIMUM_CTOOLS_API_VERSION, MODULENAME_MAXIMUM_CTOOLS_API_VERSION)) { + * $requirements['MODULENAME_ctools'] = array( + * 'title' => $t('MODULENAME required Chaos Tool Suite (CTools) API Version'), + * 'value' => t('Between @a and @b', array('@a' => MODULENAME_MINIMUM_CTOOLS_API_VERSION, '@b' => MODULENAME_MAXIMUM_CTOOLS_API_VERSION)), + * 'severity' => REQUIREMENT_ERROR, + * ); + * } + * return $requirements; + * } + * @endcode + * + * Please note that the version is a string, not an floating point number. + * This will matter once CTools reaches version 1.10. + * + * A CTools API changes history will be kept in API.txt. Not every new + * version of CTools will necessarily update the API version. + * @param $minimum + * The minimum version of CTools necessary for your software to run with it. + * @param $maximum + * The maximum version of CTools allowed for your software to run with it. + */ +function ctools_api_version($minimum, $maximum = NULL) { + if (version_compare(CTOOLS_API_VERSION, $minimum, '<')) { + return FALSE; + } + + if (isset($maximum) && version_compare(CTOOLS_API_VERSION, $maximum, '>')) { + return FALSE; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- +// General utility functions + +/** + * Include .inc files as necessary. + * + * This fuction is helpful for including .inc files for your module. The + * general case is including ctools funcitonality like this: + * + * @code + * ctools_include('plugins'); + * @endcode + * + * Similar funcitonality can be used for other modules by providing the $module + * and $dir arguments like this: + * + * @code + * // include mymodule/includes/import.inc + * ctools_include('import', 'mymodule'); + * // include mymodule/plugins/foobar.inc + * ctools_include('foobar', 'mymodule', 'plugins'); + * @endcode + * + * @param $file + * The base file name to be included. + * @param $module + * Optional module containing the include. + * @param $dir + * Optional subdirectory containing the include file. + */ +function ctools_include($file, $module = 'ctools', $dir = 'includes') { + static $used = array(); + + $dir = '/' . ($dir ? $dir . '/' : ''); + + if (!isset($used[$module][$dir][$file])) { + require_once './' . drupal_get_path('module', $module) . "$dir$file.inc"; + $used[$module][$dir][$file] = true; + } +} + +/** + * Provide the proper path to an image as necessary. + * + * This helper function is used by ctools but can also be used in other + * modules in the same way as explained in the comments of ctools_include. + * + * @param $image + * The base file name (with extension) of the image to be included. + * @param $module + * Optional module containing the include. + * @param $dir + * Optional subdirectory containing the include file. + */ +function ctools_image_path($image, $module = 'ctools', $dir = 'images') { + return drupal_get_path('module', $module) . "/$dir/" . $image; +} + +/** + * Include css files as necessary. + * + * This helper function is used by ctools but can also be used in other + * modules in the same way as explained in the comments of ctools_include. + * + * @param $file + * The base file name to be included. + * @param $module + * Optional module containing the include. + * @param $dir + * Optional subdirectory containing the include file. + */ +function ctools_add_css($file, $module = 'ctools', $dir = 'css') { + drupal_add_css(drupal_get_path('module', $module) . "/$dir/$file.css"); +} + +/** + * Include js files as necessary. + * + * This helper function is used by ctools but can also be used in other + * modules in the same way as explained in the comments of ctools_include. + * + * @param $file + * The base file name to be included. + * @param $module + * Optional module containing the include. + * @param $dir + * Optional subdirectory containing the include file. + */ +function ctools_add_js($file, $module = 'ctools', $dir = 'js') { + drupal_add_js(drupal_get_path('module', $module) . "/$dir/$file.js"); +} + +/** + * Central static variable storage. Modeled after Drupal 7's drupal_static(). + * + * @param $name + * Globally unique name for the variable. For a function with only one static, + * variable, the function name (e.g. via the PHP magic __FUNCTION__ constant) + * is recommended. For a function with multiple static variables add a + * distinguishing suffix to the function name for each one. + * @param $default_value + * Optional default value. + * @param $reset + * TRUE to reset a specific named variable, or all variables if $name is NULL. + * Resetting every variable should only be used, for example, for running unit + * tests with a clean environment. Should be used only though via function + * ctools_static_reset(). + */ +function &ctools_static($name, $default_value = NULL, $reset = FALSE) { + static $data = array(); + + // Reset a single value, or all values. + if ($reset) { + if (isset($name)) { + unset($data[$name]); + } + else { + $data = array(); + } + // We must return a reference to a variable. + $dummy = NULL; + return $dummy; + } + + if (!isset($data[$name])) { + $data[$name] = $default_value; + } + + return $data[$name]; +} + +/** + * Reset one or all centrally stored static variable(s). + * Modeled after Drupal 7's drupal_static_reset(). + * + * @param $name + * Name of the static variable to reset. Omit to reset all variables. + */ +function ctools_static_reset($name) { + ctools_static($name, NULL, TRUE); +} + +/** + * Get a list of roles in the system. + * + * @return + * An array of role names keyed by role ID. + */ +function ctools_get_roles() { + static $roles = NULL; + if (!isset($roles)) { + $roles = array(); + $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name"); + while ($obj = db_fetch_object($result)) { + $roles[$obj->rid] = $obj->name; + } + } + + return $roles; +} + +/* + * Break x,y,z and x+y+z into an array. Numeric only. + * + * @param $str + * The string to parse. + * + * @return $object + * An object containing + * - operator: Either 'and' or 'or' + * - value: An array of numeric values. + */ +function ctools_break_phrase($str) { + $object = new stdClass(); + + if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str)) { + // The '+' character in a query string may be parsed as ' '. + $object->operator = 'or'; + $object->value = preg_split('/[+ ]/', $str); + } + else if (preg_match('/^([0-9]+,)*[0-9]+$/', $str)) { + $object->operator = 'and'; + $object->value = explode(',', $str); + } + + // Keep an 'error' value if invalid strings were given. + if (!empty($str) && (empty($object->value) || !is_array($object->value))) { + $object->value = array(-1); + $object->invalid_input = TRUE; + return $object; + } + + if (empty($object->value)) { + $object->value = array(); + } + + // Doubly ensure that all values are numeric only. + foreach ($object->value as $id => $value) { + $object->value[$id] = intval($value); + } + + return $object; +} + +/** + * Set a token/value pair to be replaced later in the request, specifically in + * ctools_preprocess_page(). + * + * @param $token + * The token to be replaced later, during page rendering. This should + * ideally be a string inside of an HTML comment, so that if there is + * no replacement, the token will not render on the page. + * @param $type + * The type of the token. Can be either 'variable', which will pull data + * directly from the page variables + * @param $argument + * If $type == 'variable' then argument should be the key to fetch from + * the $variables. If $type == 'callback' then it should either be the + * callback, or an array that will be sent to call_user_func_array(). + * + * @return + * A array of token/variable names to be replaced. + */ +function ctools_set_page_token($token = NULL, $type = NULL, $argument = NULL) { + static $tokens = array(); + + if (isset($token)) { + $tokens[$token] = array($type, $argument); + } + + return $tokens; +} + +/** + * Easily set a token from the page variables. + * + * This function can be used like this: + * $token = ctools_set_variable_token('tabs'); + * + * $token will then be a simple replacement for the 'tabs' about of the + * variables available in the page template. + */ +function ctools_set_variable_token($token) { + $string = '<!-- ctools-page-' . $token . ' -->'; + ctools_set_page_token($string, 'variable', $token); + return $string; +} + +/** + * Easily set a token from the page variables. + * + * This function can be used like this: + * $token = ctools_set_variable_token('id', 'mymodule_myfunction'); + */ +function ctools_set_callback_token($token, $callback) { + // If the callback uses arguments they are considered in the token. + if (is_array($callback)) { + $token .= '-' . md5(serialize($callback)); + } + $string = '<!-- ctools-page-' . $token . ' -->'; + ctools_set_page_token($string, 'callback', $callback); + return $string; +} + +// ----------------------------------------------------------------------- +// Drupal core hooks + +/** + * Implement hook_init to keep our global CSS at the ready. + */ +function ctools_init() { + ctools_add_css('ctools'); + // If we are sure that CTools' AJAX is in use, change the error handling. + if (!empty($_REQUEST['ctools_ajax'])) { + ini_set('display_errors', 0); + register_shutdown_function('ctools_shutdown_handler'); + } + + // Clear plugin cache on the module page submit. + if ($_GET['q'] == 'admin/build/modules/list/confirm' && !empty($_POST)) { + cache_clear_all('ctools_plugin_files:', 'cache', TRUE); + } +} + +/** + * Shutdown handler used during ajax operations to help catch fatal errors. + */ +function ctools_shutdown_handler() { + if (function_exists('error_get_last') AND ($error = error_get_last())){ + switch($error['type']){ + case E_ERROR: + case E_CORE_ERROR: + case E_COMPILE_ERROR: + case E_USER_ERROR: + // Do this manually because including files here is dangerous. + $commands = array( + array( + 'command' => 'alert', + 'title' => t('Error'), + 'text' => t('Unable to complete operation. Fatal error in @file on line @line: @message', array( + '@file' => $error['file'], + '@line' => $error['line'], + '@message' => $error['message'], + )), + ), + ); + + // Change the status code so that the client will read the AJAX returned. + header('HTTP/1.1 200 OK'); + drupal_json($commands); + } + } +} + +/** + * Implementation of hook_theme(). + */ +function ctools_theme() { + ctools_include('utility'); + $items = array(); + ctools_passthrough('ctools', 'theme', $items); + return $items; +} + +/** + * Implementation of hook_menu(). + */ +function ctools_menu() { + ctools_include('utility'); + $items = array(); + ctools_passthrough('ctools', 'menu', $items); + return $items; +} + +/** + * Implementation of hook_cron. Clean up old caches. + */ +function ctools_cron() { + ctools_include('utility'); + $items = array(); + ctools_passthrough('ctools', 'cron', $items); +} + +/** + * Ensure the CTools CSS cache is flushed whenever hook_flush_caches is invoked. + */ +function ctools_flush_caches() { + // Do not actually flush caches if running on cron. Drupal uses this hook + // in an inconsistent fashion and it does not necessarily mean to *flush* + // caches when running from cron. Instead it's just getting a list of cache + // tables and may not do any flushing. + if (variable_get('cron_semaphore', FALSE)) { + return; + } + + ctools_include('css'); + ctools_css_flush_caches(); +} + +/** + * Provide a search form with a different id so that form_alters will miss it + * and thus not get advanced search settings. + */ +function ctools_forms() { + $forms['ctools_search_form']= array( + 'callback' => 'search_form', + ); + + return $forms; +} + +/** + * Implements hook_form_alter(). + */ +function ctools_form_alter(&$form, $form_state, $form_id) { + $form['#after_build'][] = 'ctools_ajax_form_after_build'; +} + +/** + * #after_build callback: Mark the $form['#action'] as a trusted URL for Ajax. + */ +function ctools_ajax_form_after_build($form, $form_state) { + $settings = array( + 'CToolsUrlIsAjaxTrusted' => array( + $form['#action'] => TRUE, + ), + ); + drupal_add_js($settings, 'setting'); + return $form; +} + +/** + * Implementation of hook_file_download() + * + * When using the private file system, we have to let Drupal know it's ok to + * download CSS and image files from our temporary directory. + */ +function ctools_file_download($filepath) { + if (strpos($filepath, 'ctools') === 0) { + $mime = file_get_mimetype($filepath); + // For safety's sake, we allow only text and images. + if (strpos($mime, 'text') === 0 || strpos($mime, 'image') === 0) { + return array('Content-type:' . $mime); + } + } +} + +// ----------------------------------------------------------------------- +// CTools hook implementations. + +/** + * Implementation of hook_ctools_plugin_directory() to let the system know + * where all our own plugins are. + */ +function ctools_ctools_plugin_directory($owner, $plugin_type) { + if ($owner == 'ctools') { + return 'plugins/' . $plugin_type; + } +} + +/** + * Implementation of hook_js_replacements(). + * This is a hook that is not a standard yet. We hope jquery_update and others + * will expose this hook to inform modules which scripts they are modifying + * in the theme layer. + * The return format is $scripts[$type][$old_path] = $new_path. + */ +function ctools_js_replacements() { + $replacements = array(); + // Until jquery_update is released with its own replacement hook, we will + // take those replacements into account here. + if (module_exists('jquery_update')) { + $replacements = array_merge_recursive($replacements, jquery_update_get_replacements()); + foreach ($replacements as $type => $type_replacements) { + foreach ($type_replacements as $old_path => $new_filename) { + $replacements[$type][$old_path] = drupal_get_path('module', 'jquery_update') . "/replace/$new_filename"; + } + } + $replacements['core']['misc/jquery.js'] = jquery_update_jquery_path(); + } + return $replacements; +} + +/** + * Inform CTools that the layout plugin can be loaded from themes. + */ +function ctools_ctools_plugin_access() { + return array( + 'child plugins' => TRUE, + ); +} + +// ----------------------------------------------------------------------- +// Drupal theme preprocess hooks that must be in the .module file. + +/** + * Override or insert PHPTemplate variables into the templates. + * + * This needs to be in the .module file to ensure availability; we can't change the + * paths or it won't be able to find templates. + */ +function ctools_garland_preprocess_page(&$vars) { + $vars['tabs2'] = ctools_menu_secondary_local_tasks(); + + // Hook into color.module + if (module_exists('color')) { + _color_page_alter($vars); + } +} + +/** + * A theme preprocess function to automatically allow panels-based node + * templates based upon input when the panel was configured. + */ +function ctools_preprocess_node(&$vars) { + // The 'panel_identifier' attribute of the node is added when the pane is + // rendered. + if (!empty($vars['node']->panel_identifier)) { + $vars['panel_identifier'] = check_plain($vars['node']->panel_identifier); + $vars['template_files'][] = 'node-panel-' . check_plain($vars['node']->panel_identifier); + } +} + +/** + * A theme preprocess function to allow content type plugins to use page + * template variables which are not yet available when the content type is + * rendered. + */ +function ctools_preprocess_page(&$variables) { + $tokens = ctools_set_page_token(); + if (!empty($tokens)) { + $temp_tokens = array(); + foreach ($tokens as $token => $key) { + list($type, $argument) = $key; + switch ($type) { + case 'variable': + $temp_tokens[$token] = isset($variables[$argument]) ? $variables[$argument] : ''; + break; + case 'callback': + if (is_string($argument) && function_exists($argument)) { + $temp_tokens[$token] = $argument($variables); + } + if (is_array($argument) && function_exists($argument[0])) { + $function = array_shift($argument); + $argument = array_merge(array(&$variables), $argument); + $temp_tokens[$token] = call_user_func_array($function, $argument); + } + break; + } + } + $tokens = $temp_tokens; + unset($temp_tokens); + $variables['content'] = strtr($variables['content'], $tokens); + } + + if (defined('CTOOLS_AJAX_INCLUDED')) { + ctools_ajax_page_preprocess($variables); + } +} + +// ----------------------------------------------------------------------- +// Menu callbacks that must be in the .module file. + +/** + * Determine if the current user has access via a plugin. + * + * This function is meant to be embedded in the Drupal menu system, and + * therefore is in the .module file since sub files can't be loaded, and + * takes arguments a little bit more haphazardly than ctools_access(). + * + * @param $access + * An access control array which contains the following information: + * - 'logic': and or or. Whether all tests must pass or one must pass. + * - 'plugins': An array of access plugins. Each contains: + * - - 'name': The name of the plugin + * - - 'settings': The settings from the plugin UI. + * - - 'context': Which context to use. + * @param ... + * zero or more context arguments generated from argument plugins. These + * contexts must have an 'id' attached to them so that they can be + * properly associated. The argument plugin system should set this, but + * if the context is coming from elsewhere it will need to be set manually. + * + * @return + * TRUE if access is granted, false if otherwise. + */ +function ctools_access_menu($access) { + // Short circuit everything if there are no access tests. + if (empty($access['plugins'])) { + return TRUE; + } + + $contexts = array(); + foreach (func_get_args() as $arg) { + if (is_object($arg) && get_class($arg) == 'ctools_context') { + $contexts[$arg->id] = $arg; + } + } + + ctools_include('context'); + return ctools_access($access, $contexts); +} + +/** + * Determine if the current user has access via checks to multiple different + * permissions. + * + * This function is a thin wrapper around user_access that allows multiple + * permissions to be easily designated for use on, for example, a menu callback. + * + * @param ... + * An indexed array of zero or more permission strings to be checked by + * user_access(). + * + * @return + * Iff all checks pass will this function return TRUE. If an invalid argument + * is passed (e.g., not a string), this function errs on the safe said and + * returns FALSE. + */ +function ctools_access_multiperm() { + foreach (func_get_args() as $arg) { + if (!is_string($arg) || !user_access($arg)) { + return FALSE; + } + } + return TRUE; +} + +/** + * Check to see if the incoming menu item is js capable or not. + * + * This can be used as %ctools_js as part of a path in hook menu. CTools + * ajax functions will automatically change the phrase 'nojs' to 'ajax' + * when it attaches ajax to a link. This can be used to autodetect if + * that happened. + */ +function ctools_js_load($js) { + if ($js == 'ajax') { + return TRUE; + } + return 0; +} + +/** + * Menu _load hook. + * + * This function will be called to load an object as a replacement for + * %ctools_export_ui in menu paths. + */ +function ctools_export_ui_load($item_name, $plugin_name) { + $return = &ctools_static(__FUNCTION__, FALSE); + + if (!$return) { + ctools_include('export-ui'); + $plugin = ctools_get_export_ui($plugin_name); + + if ($plugin) { + // Get the load callback. + $item = ctools_export_crud_load($plugin['schema'], $item_name); + return empty($item) ? FALSE : $item; + } + } + + return $return; +} + +// ----------------------------------------------------------------------- +// Caching callbacks on behalf of export-ui. + +/** + * Menu access callback for various tasks of export-ui. + */ +function ctools_export_ui_task_access($plugin_name, $op, $item = NULL) { + ctools_include('export-ui'); + $plugin = ctools_get_export_ui($plugin_name); + $handler = ctools_export_ui_get_handler($plugin); + + if ($handler) { + return $handler->access($op, $item); + } + + // Deny access if the handler cannot be found. + return FALSE; +} + +/** + * Cache callback on behalf of ctools_export_ui. + */ +function ctools_export_ui_context_cache_get($plugin_name, $key) { + ctools_include('export-ui'); + $plugin = ctools_get_export_ui($plugin_name); + $handler = ctools_export_ui_get_handler($plugin); + if ($handler) { + $item = $handler->edit_cache_get($key); + if (!$item) { + $item = ctools_export_crud_load($handler->plugin['schema'], $key); + } + return $item; + } +} + +/** + * Cache callback on behalf of ctools_export_ui. + */ +function ctools_export_ui_context_cache_set($plugin_name, $key, $item) { + ctools_include('export-ui'); + $plugin = ctools_get_export_ui($plugin_name); + $handler = ctools_export_ui_get_handler($plugin); + if ($handler) { + return $handler->edit_cache_set_key($item, $key); + } +} + +/** + * Callback for access control ajax form on behalf of export ui. + * + * Returns the cached access config and contexts used. + * Note that this is assuming that access will be in $item->access -- if it + * is not, an export UI plugin will have to make its own callbacks. + */ +function ctools_export_ui_ctools_access_get($argument) { + ctools_include('export-ui'); + list($plugin_name, $key) = explode(':', $argument); + + $plugin = ctools_get_export_ui($plugin_name); + $handler = ctools_export_ui_get_handler($plugin); + + if ($handler) { + ctools_include('context'); + $item = $handler->edit_cache_get($key); + if (!$item) { + $item = ctools_export_crud_load($handler->plugin['schema'], $key); + } + + $contexts = ctools_context_load_contexts($item); + return array($item->access, $contexts); + } +} + +/** + * Callback for access control ajax form on behalf of export ui + * + * Returns the cached access config and contexts used. + * Note that this is assuming that access will be in $item->access -- if it + * is not, an export UI plugin will have to make its own callbacks. + */ +function ctools_export_ui_ctools_access_set($argument, $access) { + ctools_include('export-ui'); + list($plugin_name, $key) = explode(':', $argument); + + $plugin = ctools_get_export_ui($plugin_name); + $handler = ctools_export_ui_get_handler($plugin); + + if ($handler) { + ctools_include('context'); + $item = $handler->edit_cache_get($key); + if (!$item) { + $item = ctools_export_crud_load($handler->plugin['schema'], $key); + } + $item->access = $access; + return $handler->edit_cache_set_key($item, $key); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.info b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.info new file mode 100644 index 0000000000000000000000000000000000000000..c528645e3b7dcbcc507ed8907c3493005063046f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.info @@ -0,0 +1,12 @@ +name = Custom rulesets +description = Create custom, exportable, reusable access rulesets for applications like Panels. +core = 6.x +package = Chaos tool suite +dependencies[] = ctools + +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.install b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.install new file mode 100644 index 0000000000000000000000000000000000000000..f6adc587b824565a2f843a2070f72fae38d953d0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.install @@ -0,0 +1,96 @@ +<?php + +/** + * Schema for customizable access rulesets. + */ +function ctools_access_ruleset_schema() { + return ctools_access_ruleset_schema_1(); +} + +function ctools_access_ruleset_schema_1() { + $schema = array(); + + $schema['ctools_access_ruleset'] = array( + 'description' => 'Contains exportable customized access rulesets.', + 'export' => array( + 'identifier' => 'ruleset', + 'bulk export' => TRUE, + 'primary key' => 'rsid', + 'api' => array( + 'owner' => 'ctools', + 'api' => 'ctools_rulesets', + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), + 'fields' => array( + 'rsid' => array( + 'type' => 'serial', + 'description' => 'A database primary key to ensure uniqueness', + 'not null' => TRUE, + 'no export' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this ruleset. Used to identify it programmatically.', + ), + 'admin_title' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Administrative title for this ruleset.', + ), + 'admin_description' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Administrative description for this ruleset.', + 'object default' => '', + ), + 'requiredcontexts' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Any required contexts for this ruleset.', + 'serialize' => TRUE, + 'object default' => array(), + ), + 'contexts' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Any embedded contexts for this ruleset.', + 'serialize' => TRUE, + 'object default' => array(), + ), + 'relationships' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Any relationships for this ruleset.', + 'serialize' => TRUE, + 'object default' => array(), + ), + 'access' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'The actual group of access plugins for this ruleset.', + 'serialize' => TRUE, + 'object default' => array(), + ), + ), + 'primary key' => array('rsid'), + ); + + return $schema; +} + +/** + * Implementation of hook_install(). + */ +function ctools_access_ruleset_install() { + drupal_install_schema('ctools_access_ruleset'); +} + +/** + * Implementation of hook_uninstall(). + */ +function ctools_access_ruleset_uninstall() { + drupal_uninstall_schema('ctools_access_ruleset'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.module b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.module new file mode 100644 index 0000000000000000000000000000000000000000..936f671d58f4fc77d917ddcaea92a87b9c8331ca --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/ctools_access_ruleset.module @@ -0,0 +1,82 @@ +<?php + +/** + * @file + * ctools_access_ruleset module + * + * This module allows styles to be created and managed on behalf of modules + * that implement styles. + * + * The ctools_access_ruleset tool allows recolorable styles to be created via a miniature + * scripting language. Panels utilizes this to allow administrators to add + * styles directly to any panel display. + */ + +/** + * Implementation of hook_perm() + */ +function ctools_access_ruleset_perm() { + return array( + 'administer ctools access ruleset', + ); +} + +/** + * Implementation of hook_ctools_plugin_directory() to let the system know + * we implement task and task_handler plugins. + */ +function ctools_access_ruleset_ctools_plugin_directory($module, $plugin) { + // Most of this module is implemented as an export ui plugin, and the + // rest is in ctools/includes/ctools_access_ruleset.inc + if ($module == 'ctools' && ($plugin == 'export_ui' || $plugin == 'access')) { + return 'plugins/' . $plugin; + } +} + +/** + * Implementation of hook_panels_dashboard_blocks(). + * + * Adds page information to the Panels dashboard. + */ +function ctools_access_ruleset_panels_dashboard_blocks(&$vars) { + $vars['links']['ctools_access_ruleset'] = array( + 'title' => l(t('Custom ruleset'), 'admin/build/ctools-rulesets/add'), + 'description' => t('Custom rulesets are combinations of access plugins you can use for access control, selection criteria and pane visibility.'), + ); + + // Load all mini panels and their displays. + ctools_include('export'); + $items = ctools_export_crud_load_all('ctools_access_ruleset'); + $count = 0; + $rows = array(); + + foreach ($items as $item) { + $rows[] = array( + check_plain($item->admin_title), + array( + 'data' => l(t('Edit'), "admin/build/ctools-rulesets/list/$item->name/edit"), + 'class' => 'links', + ), + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + + if ($rows) { + $content = theme('table', array(), $rows, array('class' => 'panels-manage')); + } + else { + $content = '<p>' . t('There are no custom rulesets.') . '</p>'; + } + + $vars['blocks']['ctools_access_ruleset'] = array( + 'title' => t('Manage custom rulesets'), + 'link' => l(t('Go to list'), 'admin/build/ctools-rulesets'), + 'content' => $content, + 'class' => 'dashboard-ruleset', + 'section' => 'right', + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/access/ruleset.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/access/ruleset.inc new file mode 100644 index 0000000000000000000000000000000000000000..fc8615e2d0b4d17cd8be84acee2e2d4269285f26 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/access/ruleset.inc @@ -0,0 +1,100 @@ +<?php + +/** + * @file + * Plugin to provide access control based on user rulesetission strings. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => '', + 'description' => '', + 'callback' => 'ctools_ruleset_ctools_access_check', + 'settings form' => 'ctools_ruleset_ctools_access_settings', + 'summary' => 'ctools_ruleset_ctools_access_summary', + + // This access plugin actually just contains child plugins that are + // exportable, UI configured rulesets. + 'get child' => 'ctools_ruleset_ctools_access_get_child', + 'get children' => 'ctools_ruleset_ctools_access_get_children', +); + +/** + * Merge the main access plugin with a loaded ruleset to form a child plugin. + */ +function ctools_ruleset_ctools_access_merge_plugin($plugin, $parent, $item) { + $plugin['name'] = $parent . ':' . $item->name; + $plugin['title'] = check_plain($item->admin_title); + $plugin['description'] = check_plain($item->admin_description); + + // TODO: Generalize this in CTools. + if (!empty($item->requiredcontexts)) { + $plugin['required context'] = array(); + foreach ($item->requiredcontexts as $context) { + $info = ctools_get_context($context['name']); + // TODO: allow an optional setting + $plugin['required context'][] = new ctools_context_required($context['identifier'], $info['context name']); + } + } + + // Store the loaded ruleset in the plugin. + $plugin['ruleset'] = $item; + return $plugin; +} + +/** + * Get a single child access plugin. + */ +function ctools_ruleset_ctools_access_get_child($plugin, $parent, $child) { + ctools_include('export'); + $item = ctools_export_crud_load('ctools_access_ruleset', $child); + if ($item) { + return ctools_ruleset_ctools_access_merge_plugin($plugin, $parent, $item); + } +} + +/** + * Get all child access plugins. + */ +function ctools_ruleset_ctools_access_get_children($plugin, $parent) { + $plugins = array(); + ctools_include('export'); + $items = ctools_export_crud_load_all('ctools_access_ruleset'); + foreach ($items as $name => $item) { + $child = ctools_ruleset_ctools_access_merge_plugin($plugin, $parent, $item); + $plugins[$child['name']] = $child; + } + + return $plugins; +} + +/** + * Settings form for the 'by ruleset' access plugin + */ +function ctools_ruleset_ctools_access_settings(&$form, &$form_state, $conf) { + $form['markup'] = array( + '#value' => '<div class="description">' . check_plain($form_state['plugin']['ruleset']->admin_description) . '</div>', + ); +} + +/** + * Check for access. + */ +function ctools_ruleset_ctools_access_check($conf, $context, $plugin) { + // Load up any contexts we might be using. + $contexts = ctools_context_match_required_contexts($plugin['ruleset']->requiredcontexts, $context); + $contexts = ctools_context_load_contexts($plugin['ruleset'], FALSE, $contexts); + + return ctools_access($plugin['ruleset']->access, $contexts); +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_ruleset_ctools_access_summary($conf, $context, $plugin) { + return check_plain($plugin['ruleset']->admin_description); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset.inc new file mode 100644 index 0000000000000000000000000000000000000000..bd4b1ac11e55e459ff45c3610472b2fbb0903ff0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset.inc @@ -0,0 +1,32 @@ +<?php + +$plugin = array( + 'schema' => 'ctools_access_ruleset', + 'access' => 'administer ctools access ruleset', + + 'menu' => array( + 'menu item' => 'ctools-rulesets', + 'menu title' => 'Custom access rulesets', + 'menu description' => 'Add, edit or delete custom access rulesets for use with Panels and other systems that utilize CTools content plugins.', + ), + + 'title singular' => t('ruleset'), + 'title singular proper' => t('Ruleset'), + 'title plural' => t('rulesets'), + 'title plural proper' => t('Rulesets'), + + 'handler' => array( + 'class' => 'ctools_access_ruleset_ui', + 'parent' => 'ctools_export_ui', + ), + + 'use wizard' => TRUE, + 'form info' => array( + 'order' => array( + 'basic' => t('Basic information'), + 'context' => t('Contexts'), + 'rules' => t('Rules'), + ), + ), +); + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset_ui.class.php b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..60e08b8121510e9daebc8cb252ed5c4d6f1d8c18 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset_ui.class.php @@ -0,0 +1,53 @@ +<?php + +class ctools_access_ruleset_ui extends ctools_export_ui { + + function edit_form_context(&$form, &$form_state) { + ctools_include('context-admin'); + ctools_context_admin_includes(); + ctools_add_css('ruleset'); + + $form['right'] = array( + '#prefix' => '<div class="ctools-right-container">', + '#suffix' => '</div>', + ); + + $form['left'] = array( + '#prefix' => '<div class="ctools-left-container clear-block">', + '#suffix' => '</div>', + ); + + // Set this up and we can use CTools' Export UI's built in wizard caching, + // which already has callbacks for the context cache under this name. + $module = 'ctools_export_ui-' . $this->plugin['name']; + $name = $this->edit_cache_get_key($form_state['item'], $form_state['form type']); + + ctools_context_add_context_form($module, $form, $form_state, $form['right']['contexts_table'], $form_state['item'], $name); + ctools_context_add_required_context_form($module, $form, $form_state, $form['left']['required_contexts_table'], $form_state['item'], $name); + ctools_context_add_relationship_form($module, $form, $form_state, $form['right']['relationships_table'], $form_state['item'], $name); + } + + function edit_form_rules(&$form, &$form_state) { + // The 'access' UI passes everything via $form_state, unlike the 'context' UI. + // The main difference is that one is about 3 years newer than the other. + ctools_include('context'); + ctools_include('context-access-admin'); + + $form_state['access'] = $form_state['item']->access; + $form_state['contexts'] = ctools_context_load_contexts($form_state['item']); + + $form_state['module'] = 'ctools_export_ui'; + $form_state['callback argument'] = $form_state['object']->plugin['name'] . ':' . $form_state['object']->edit_cache_get_key($form_state['item'], $form_state['form type']); + $form_state['no buttons'] = TRUE; + + $form = array_merge($form, ctools_access_admin_form($form_state)); + } + + function edit_form_rules_submit(&$form, &$form_state) { + $form_state['item']->access['logic'] = $form_state['values']['logic']; + } + + function edit_form_submit(&$form, &$form_state) { + parent::edit_form_submit($form, $form_state); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/css/ctools-ajax-sample.css b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/css/ctools-ajax-sample.css new file mode 100644 index 0000000000000000000000000000000000000000..dc83b0b0f95e0350306f28f02cc43315fdcd61f5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/css/ctools-ajax-sample.css @@ -0,0 +1,134 @@ +div.ctools-sample-modal-content { + background:none; + border:0; + color:#000000; + margin:0; + padding:0; + text-align:left; +} +div.ctools-sample-modal-content .modal-scroll{ + overflow:hidden; + overflow-y:auto; +} +div.ctools-sample-modal-content #popups-overlay { + background-color:transparent; +} +div.ctools-sample-modal-content #popups-loading { + width:248px; + position:absolute; + display:none; + opacity:1; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + z-index:99; +} +div.ctools-sample-modal-content #popups-loading span.popups-loading-message { + background:#FFF url(../images/loading-large.gif) no-repeat 8px center; + display:block; + color:#444444; + font-family:Arial; + font-size:22px; + font-weight:bold; + height:36px; + line-height:36px; + padding:0 40px; +} +div.ctools-sample-modal-content #popups-loading table, +div.ctools-sample-modal-content .popups-box table { + margin:0px; +} +div.ctools-sample-modal-content #popups-loading tbody, +div.ctools-sample-modal-content .popups-box tbody { + border:none; +} +div.ctools-sample-modal-content .popups-box tr { + background-color:transparent; +} +div.ctools-sample-modal-content td.popups-border { + background: url(../images/popups-border.png); + background-color:transparent; +} +div.ctools-sample-modal-content td.popups-tl, +div.ctools-sample-modal-content td.popups-tr, +div.ctools-sample-modal-content td.popups-bl, +div.ctools-sample-modal-content td.popups-br { + background-repeat: no-repeat; + height:10px; + padding:0px; +} +div.ctools-sample-modal-content td.popups-tl { background-position: 0px 0px; } +div.ctools-sample-modal-content td.popups-t, +div.ctools-sample-modal-content td.popups-b { + background-position: 0px -40px; + background-repeat: repeat-x; + height:10px; +} +div.ctools-sample-modal-content td.popups-tr { background-position: 0px -10px; } +div.ctools-sample-modal-content td.popups-cl, +div.ctools-sample-modal-content td.popups-cr { + background-position: -10px 0; + background-repeat: repeat-y; + width:10px; +} +div.ctools-sample-modal-content td.popups-cl, +div.ctools-sample-modal-content td.popups-cr, +div.ctools-sample-modal-content td.popups-c { padding:0; } +div.ctools-sample-modal-content td.popups-c { background:#fff; } +div.ctools-sample-modal-content td.popups-bl { background-position: 0px -20px; } +div.ctools-sample-modal-content td.popups-br { background-position: 0px -30px; } + +div.ctools-sample-modal-content .popups-box, +div.ctools-sample-modal-content #popups-loading { + border: 0px solid #454545; + opacity:1; + overflow:hidden; + padding:0; + background-color:transparent; +} +div.ctools-sample-modal-content .popups-container { + overflow:hidden; + height:100%; + background-color:#fff; +} +div.ctools-sample-modal-content div.popups-title { + -moz-border-radius-topleft: 0px; + -webkit-border-radius-topleft: 0px; + margin-bottom:0px; + background-color:#ff7200; + border:1px solid #ce5c00; + padding:4px 10px 5px; + color:white; + font-size:1em; + font-weight:bold; +} +div.ctools-sample-modal-content .popups-body { + background-color:#fff; + padding:8px; +} +div.ctools-sample-modal-content .popups-box .popups-buttons, +div.ctools-sample-modal-content .popups-box .popups-footer { + background-color:#fff; +} +div.ctools-sample-modal-content .popups-title a.close { + color: #fff; + text-decoration:none; +} +div.ctools-sample-modal-content .popups-close { + font-size:120%; + float:right; + text-align:right; +} +div.ctools-sample-modal-content .modal-loading-wrapper { + width:220px; + height:19px; + margin:0 auto; + margin-top:2%; +} + +div.ctools-sample-modal-content tbody{ + border:none; +} + +div.ctools-sample-modal-content .modal-content .modal-throbber-wrapper img { + margin-top: 100px; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.info b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.info new file mode 100644 index 0000000000000000000000000000000000000000..6c873e4aa02a2255f95ef3183532b1b3866a1018 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.info @@ -0,0 +1,12 @@ +name = Chaos Tools (CTools) AJAX Example +description = Shows how to use the power of Chaos AJAX. +package = Chaos tool suite +dependencies[] = ctools +version = "6.x-1.0" +core = "6.x" +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.install b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.install new file mode 100644 index 0000000000000000000000000000000000000000..04325dbf418b23d2d5d2ead9498fea9763c853bf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.install @@ -0,0 +1,19 @@ +<?php + +/** + * @file + */ + +/** + * Implementation of hook_install() + */ +function ctools_ajax_sample_install() { + +} + +/** + * Implementation of hook_uninstall() + */ +function ctools_ajax_sample_uninstall() { + +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.module b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.module new file mode 100644 index 0000000000000000000000000000000000000000..a04df9f0b9b85a8b1ef3b4171ef16bf65f10c0e5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/ctools_ajax_sample.module @@ -0,0 +1,645 @@ +<?php + +/** + * @file + * Sample AJAX functionality so people can see some of the CTools AJAX + * features in use. + */ + +// --------------------------------------------------------------------------- +// Drupal hooks. + +/** + * Implementation of hook_menu() + */ +function ctools_ajax_sample_menu() { + $items['ctools_ajax_sample'] = array( + 'title' => 'Chaos Tools AJAX Demo', + 'page callback' => 'ctools_ajax_sample_page', + 'access callback' => TRUE, + 'type' => MENU_NORMAL_ITEM, + ); + $items['ctools_ajax_sample/%ctools_js/hello'] = array( + 'title' => 'Hello World', + 'page callback' => 'ctools_ajax_sample_hello', + 'page arguments' => array(1), + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); + $items['ctools_ajax_sample/%ctools_js/tablenix/%'] = array( + 'title' => 'Hello World', + 'page callback' => 'ctools_ajax_sample_tablenix', + 'page arguments' => array(1, 3), + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); + $items['ctools_ajax_sample/%ctools_js/login'] = array( + 'title' => 'Login', + 'page callback' => 'ctools_ajax_sample_login', + 'page arguments' => array(1), + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); + $items['ctools_ajax_sample/%ctools_js/animal'] = array( + 'title' => 'Animal', + 'page callback' => 'ctools_ajax_sample_animal', + 'page arguments' => array(1), + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); + $items['ctools_ajax_sample/%ctools_js/login/%'] = array( + 'title' => 'Post-Login Action', + 'page callback' => 'ctools_ajax_sample_login_success', + 'page arguments' => array(1, 3), + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); + + return $items; +} + +/** + * Implementation of hook_theme() + * + * Render some basic output for this module. + */ +function ctools_ajax_sample_theme() { + return array( + // Sample theme functions. + 'ctools_ajax_sample_container' => array( + 'arguments' => array('content' => NULL), + ), + ); +} + +// --------------------------------------------------------------------------- +// Page callbacks + +/** + * Page callback to display links and render a container for AJAX stuff. + */ +function ctools_ajax_sample_page() { + global $user; + + // Include the CTools tools that we need. + ctools_include('ajax'); + ctools_include('modal'); + + // Add CTools' javascript to the page. + ctools_modal_add_js(); + + // Create our own javascript that will be used to theme a modal. + $sample_style = array( + 'ctools-sample-style' => array( + 'modalSize' => array( + 'type' => 'fixed', + 'width' => 500, + 'height' => 300, + 'addWidth' => 20, + 'addHeight' => 15, + ), + 'modalOptions' => array( + 'opacity' => .5, + 'background-color' => '#000', + ), + 'animation' => 'fadeIn', + 'modalTheme' => 'CToolsSampleModal', + 'throbber' => theme('image', ctools_image_path('ajax-loader.gif', 'ctools_ajax_sample'), t('Loading...'), t('Loading')), + ), + ); + + drupal_add_js($sample_style, 'setting'); + + // Since we have our js, css and images in well-known named directories, + // CTools makes it easy for us to just use them without worrying about + // using drupal_get_path() and all that ugliness. + ctools_add_js('ctools-ajax-sample', 'ctools_ajax_sample'); + ctools_add_css('ctools-ajax-sample', 'ctools_ajax_sample'); + + // Create a list of clickable links. + $links = array(); + + // Only show login links to the anonymous user. + if ($user->uid == 0) { + $links[] = ctools_modal_text_button(t('Modal Login (default style)'), 'ctools_ajax_sample/nojs/login', t('Login via modal')); + + // The extra class points to the info in ctools-sample-style which we added to the settings. + $links[] = ctools_modal_text_button(t('Modal Login (custom style)'), 'ctools_ajax_sample/nojs/login', t('Login via modal'), 'ctools-modal-ctools-sample-style'); + } + + // Three ways to do our animal picking wizard. + $links[] = l(t('Wizard (no modal)'), 'ctools_ajax_sample/nojs/animal'); + $links[] = ctools_modal_text_button(t('Wizard (default modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal')); + $links[] = ctools_modal_text_button(t('Wizard (custom modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'), 'ctools-modal-ctools-sample-style'); + + $links[] = ctools_ajax_text_button(t('Hello world!'), "ctools_ajax_sample/nojs/hello", t('Replace text with "hello world"')); + + $output = theme('item_list', $links, t('Actions')); + + // This container will have data AJAXed into it. + $output .= theme('ctools_ajax_sample_container', '<h1>' . t('Sample Content') . '</h1>'); + + // Create a table that we can have data removed from via AJAX. + $header = array(t('Row'), t('Content'), t('Actions')); + $rows = array(); + for($i = 1; $i < 11; $i++) { + $rows[] = array( + 'class' => 'ajax-sample-row-'. $i, + 'data' => array( + $i, + md5($i), + ctools_ajax_text_button("remove", "ctools_ajax_sample/nojs/tablenix/$i", t('Delete this row')), + ), + ); + } + + $output .= theme('table', $header, $rows, array('class' => 'ajax-sample-table')); + + return $output; +} + +/** + * Returns a "take it all over" hello world style request. + */ +function ctools_ajax_sample_hello($js = NULL) { + $output = '<h1>' . t('Hello World') . '</h1>'; + if ($js) { + ctools_include('ajax'); + $commands = array(); + $commands[] = ctools_ajax_command_html('#ctools-sample', $output); + ctools_ajax_render($commands); // this function exits. + } + else { + return $output;; + } +} + +/** + * Nix a row from a table and restripe. + */ +function ctools_ajax_sample_tablenix($js, $row) { + if (!$js) { + // We don't support degrading this from js because we're not + // using the server to remember the state of the table. + return MENU_ACCESS_DENIED; + } + ctools_include('ajax'); + + $commands = array(); + $commands[] = ctools_ajax_command_remove("tr.ajax-sample-row-$row"); + $commands[] = ctools_ajax_command_restripe("table.ajax-sample-table"); + ctools_ajax_render($commands); +} + +/** + * A modal login callback. + */ +function ctools_ajax_sample_login($js = NULL) { + // Fall back if $js is not set. + if (!$js) { + return drupal_get_form('user_login'); + } + + ctools_include('modal'); + ctools_include('ajax'); + $form_state = array( + 'title' => t('Login'), + 'ajax' => TRUE, + ); + $output = ctools_modal_form_wrapper('user_login', $form_state); + if (empty($output)) { + // empty $output signifies success, so we'll use it as our $commands + // array. + $output = array(); + $inplace = ctools_ajax_text_button(t('remain here'), 'ctools_ajax_sample/nojs/login/inplace', t('Go to your account')); + $account = ctools_ajax_text_button(t('your account'), 'ctools_ajax_sample/nojs/login/user', t('Go to your account')); + $output[] = ctools_modal_command_display(t('Login Success'), '<div class="modal-message">Login successful. You can now choose whether to '. $inplace .', or go to '. $account.'.</div>'); + } + ctools_ajax_render($output); +} + +/** + * Post-login processor: should we go to the user account or stay in place? + */ +function ctools_ajax_sample_login_success($js, $action) { + if (!$js) { + // we should never be here out of ajax context + return MENU_NOT_FOUND; + } + + ctools_include('ajax'); + $commands = array(); + if ($action == 'inplace') { + // stay here + $commands[] = ctools_ajax_command_reload(); + } + else { + // bounce bounce + $commands[] = ctools_ajax_command_redirect('user'); + } + ctools_ajax_render($commands); +} + +/** + * A modal login callback. + */ +function ctools_ajax_sample_animal($js = NULL, $step = NULL) { + if ($js) { + ctools_include('modal'); + ctools_include('ajax'); + } + + $form_info = array( + 'id' => 'animals', + 'path' => "ctools_ajax_sample/" . ($js ? 'ajax' : 'nojs') . "/animal/%step", + 'show trail' => TRUE, + 'show back' => TRUE, + 'show cancel' => TRUE, + 'show return' => FALSE, + 'next callback' => 'ctools_ajax_sample_wizard_next', + 'finish callback' => 'ctools_ajax_sample_wizard_finish', + 'cancel callback' => 'ctools_ajax_sample_wizard_cancel', + // this controls order, as well as form labels + 'order' => array( + 'start' => t('Choose animal'), + ), + // here we map a step to a form id. + 'forms' => array( + // e.g. this for the step at wombat/create + 'start' => array( + 'form id' => 'ctools_ajax_sample_start' + ), + ), + ); + + // We're not using any real storage here, so we're going to set our + // object_id to 1. When using wizard forms, id management turns + // out to be one of the hardest parts. Editing an object with an id + // is easy, but new objects don't usually have ids until somewhere + // in creation. + // + // We skip all this here by just using an id of 1. + + $object_id = 1; + + if (empty($step)) { + // We reset the form when $step is NULL because that means they have + // for whatever reason started over. + ctools_ajax_sample_cache_clear($object_id); + $step = 'start'; + } + + // This automatically gets defaults if there wasn't anything saved. + $object = ctools_ajax_sample_cache_get($object_id); + + $animals = ctools_ajax_sample_animals(); + + // Make sure we can't somehow accidentally go to an invalid animal. + if (empty($animals[$object->type])) { + $object->type = 'unknown'; + } + + // Now that we have our object, dynamically add the animal's form. + if ($object->type == 'unknown') { + // If they haven't selected a type, add a form that doesn't exist yet. + $form_info['order']['unknown'] = t('Configure animal'); + $form_info['forms']['unknown'] = array('form id' => 'nothing'); + } + else { + // Add the selected animal to the order so that it shows up properly in the trail. + $form_info['order'][$object->type] = $animals[$object->type]['config title']; + } + + // Make sure all animals forms are represented so that the next stuff can + // work correctly: + foreach ($animals as $id => $animal) { + $form_info['forms'][$id] = array('form id' => $animals[$id]['form']); + } + + $form_state = array( + 'ajax' => $js, + // Put our object and ID into the form state cache so we can easily find + // it. + 'object_id' => $object_id, + 'object' => &$object, + ); + + // Send this all off to our form. This is like drupal_get_form only wizardy. + ctools_include('wizard'); + $output = ctools_wizard_multistep_form($form_info, $step, $form_state); + + if ($output === FALSE || !empty($form_state['complete'])) { + // This creates a string based upon the animal and its setting using + // function indirection. + $animal = $animals[$object->type]['output']($object); + } + + // If $output is FALSE, there was no actual form. + if ($js) { + // If javascript is active, we have to use a render array. + $commands = array(); + if ($output === FALSE || !empty($form_state['complete'])) { + // Dismiss the modal. + $commands[] = ctools_ajax_command_html('#ctools-sample', $animal); + $commands[] = ctools_modal_command_dismiss(); + } + else if (!empty($form_state['cancel'])) { + // If cancelling, return to the activity. + $commands[] = ctools_modal_command_dismiss(); + } + else { + $commands = ctools_modal_form_render($form_state, $output); + } + ctools_ajax_render($commands); + } + else { + if ($output === FALSE || !empty($form_state['complete'])) { + return $animal; + } + else if (!empty($form_state['cancel'])) { + drupal_goto('ctools_ajax_sample'); + } + else { + return $output; + } + } +} + +// --------------------------------------------------------------------------- +// Themes + +/** + * Theme function for main rendered output. + */ +function theme_ctools_ajax_sample_container($content) { + $output = '<div id="ctools-sample">'; + $output .= $content; + $output .= '</div>'; + + return $output; +} + +// --------------------------------------------------------------------------- +// Stuff needed for our little wizard. + +/** + * Get a list of our animals and associated forms. + * + * What we're doing is making it easy to add more animals in just one place, + * which is often how it will work in the real world. If using CTools, what + * you would probably really have, here, is a set of plugins for each animal. + */ +function ctools_ajax_sample_animals() { + return array( + 'sheep' => array( + 'title' => t('Sheep'), + 'config title' => t('Configure sheep'), + 'form' => 'ctools_ajax_sample_configure_sheep', + 'output' => 'ctools_ajax_sample_show_sheep', + ), + 'lizard' => array( + 'title' => t('Lizard'), + 'config title' => t('Configure lizard'), + 'form' => 'ctools_ajax_sample_configure_lizard', + 'output' => 'ctools_ajax_sample_show_lizard', + ), + 'raptor' => array( + 'title' => t('Raptor'), + 'config title' => t('Configure raptor'), + 'form' => 'ctools_ajax_sample_configure_raptor', + 'output' => 'ctools_ajax_sample_show_raptor', + ), + ); +} + +// --------------------------------------------------------------------------- +// Wizard caching helpers. + +/** + * Store our little cache so that we can retain data from form to form. + */ +function ctools_ajax_sample_cache_set($id, $object) { + ctools_include('object-cache'); + ctools_object_cache_set('ctools_ajax_sample', $id, $object); +} + +/** + * Get the current object from the cache, or default. + */ +function ctools_ajax_sample_cache_get($id) { + ctools_include('object-cache'); + $object = ctools_object_cache_get('ctools_ajax_sample', $id); + if (!$object) { + // Create a default object. + $object = new stdClass; + $object->type = 'unknown'; + $object->name = ''; + } + + return $object; +} + +/** + * Clear the wizard cache. + */ +function ctools_ajax_sample_cache_clear($id) { + ctools_include('object-cache'); + ctools_object_cache_clear('ctools_ajax_sample', $id); +} + +// --------------------------------------------------------------------------- +// Wizard in-between helpers; what to do between or after forms. + +/** + * Handle the 'next' click on the add/edit pane form wizard. + * + * All we need to do is store the updated pane in the cache. + */ +function ctools_ajax_sample_wizard_next(&$form_state) { + ctools_ajax_sample_cache_set($form_state['object_id'], $form_state['object']); +} + +/** + * Handle the 'finish' click on teh add/edit pane form wizard. + * + * All we need to do is set a flag so the return can handle adding + * the pane. + */ +function ctools_ajax_sample_wizard_finish(&$form_state) { + $form_state['complete'] = TRUE; +} + +/** + * Handle the 'cancel' click on the add/edit pane form wizard. + */ +function ctools_ajax_sample_wizard_cancel(&$form_state) { + $form_state['cancel'] = TRUE; +} + +// --------------------------------------------------------------------------- +// Wizard forms for our simple info collection wizard. + +/** + * Wizard start form. Choose an animal. + */ +function ctools_ajax_sample_start(&$form, &$form_state) { + $form_state['title'] = t('Choose animal'); + + $animals = ctools_ajax_sample_animals(); + foreach ($animals as $id => $animal) { + $options[$id] = $animal['title']; + } + + $form['type'] = array( + '#title' => t('Choose your animal'), + '#type' => 'radios', + '#options' => $options, + '#default_value' => $form_state['object']->type, + '#required' => TRUE, + ); +} + +/** + * They have selected a sheep. Set it. + */ +function ctools_ajax_sample_start_submit(&$form, &$form_state) { + $form_state['object']->type = $form_state['values']['type']; + // Override where to go next based on the animal selected. + $form_state['clicked_button']['#next'] = $form_state['values']['type']; +} + +/** + * Wizard form to configure your sheep. + */ +function ctools_ajax_sample_configure_sheep(&$form, &$form_state) { + $form_state['title'] = t('Configure sheep'); + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Name your sheep'), + '#default_value' => $form_state['object']->name, + '#required' => TRUE, + ); + + $form['sheep'] = array( + '#title' => t('What kind of sheep'), + '#type' => 'radios', + '#options' => array( + t('Wensleydale') => t('Wensleydale'), + t('Merino') => t('Merino'), + t('Corriedale') => t('Coriedale'), + ), + '#default_value' => !empty($form_state['object']->sheep) ? $form_state['object']->sheep : '', + '#required' => TRUE, + ); +} + +/** + * Submit the sheep and store the values from the form. + */ +function ctools_ajax_sample_configure_sheep_submit(&$form, &$form_state) { + $form_state['object']->name = $form_state['values']['name']; + $form_state['object']->sheep = $form_state['values']['sheep']; +} + +/** + * Provide some output for our sheep. + */ +function ctools_ajax_sample_show_sheep($object) { + return t('You have a @type sheep named "@name".', array( + '@type' => $object->sheep, + '@name' => $object->name, + )); +} + +/** + * Wizard form to configure your lizard. + */ +function ctools_ajax_sample_configure_lizard(&$form, &$form_state) { + $form_state['title'] = t('Configure lizard'); + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Name your lizard'), + '#default_value' => $form_state['object']->name, + '#required' => TRUE, + ); + + $form['lizard'] = array( + '#title' => t('Venomous'), + '#type' => 'checkbox', + '#default_value' => !empty($form_state['object']->lizard), + ); +} + +/** + * Submit the lizard and store the values from the form. + */ +function ctools_ajax_sample_configure_lizard_submit(&$form, &$form_state) { + $form_state['object']->name = $form_state['values']['name']; + $form_state['object']->lizard = $form_state['values']['lizard']; +} + +/** + * Provide some output for our raptor. + */ +function ctools_ajax_sample_show_lizard($object) { + return t('You have a @type lizard named "@name".', array( + '@type' => empty($object->lizard) ? t('non-venomous') : t('venomous'), + '@name' => $object->name, + )); +} + +/** + * Wizard form to configure your raptor. + */ +function ctools_ajax_sample_configure_raptor(&$form, &$form_state) { + $form_state['title'] = t('Configure raptor'); + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Name your raptor'), + '#default_value' => $form_state['object']->name, + '#required' => TRUE, + ); + + $form['raptor'] = array( + '#title' => t('What kind of raptor'), + '#type' => 'radios', + '#options' => array( + t('Eagle') => t('Eagle'), + t('Hawk') => t('Hawk'), + t('Owl') => t('Owl'), + t('Buzzard') => t('Buzzard'), + ), + '#default_value' => !empty($form_state['object']->raptor) ? $form_state['object']->raptor : '', + '#required' => TRUE, + ); + + $form['domesticated'] = array( + '#title' => t('Domesticated'), + '#type' => 'checkbox', + '#default_value' => !empty($form_state['object']->domesticated), + ); + +} + +/** + * Submit the raptor and store the values from the form. + */ +function ctools_ajax_sample_configure_raptor_submit(&$form, &$form_state) { + $form_state['object']->name = $form_state['values']['name']; + $form_state['object']->raptor = $form_state['values']['raptor']; + $form_state['object']->domesticated = $form_state['values']['domesticated']; +} + +/** + * Provide some output for our raptor. + */ +function ctools_ajax_sample_show_raptor($object) { + return t('You have a @type @raptor named "@name".', array( + '@type' => empty($object->domesticated) ? t('wild') : t('domesticated'), + '@raptor' => $object->raptor, + '@name' => $object->name, + )); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/ajax-loader.gif b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..d84f653789e5008da64ff04ee109471284a9e284 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/ajax-loader.gif differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/loading-large.gif b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/loading-large.gif new file mode 100644 index 0000000000000000000000000000000000000000..1c72ebb554be018511ae972c3f2361dff02dce02 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/loading-large.gif differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/loading.gif b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..dc21df1837f54a65bbdf6a857f8358de880d63d9 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/loading.gif differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/popups-border.png b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/popups-border.png new file mode 100644 index 0000000000000000000000000000000000000000..ba939f8994e793b3aa47757c6227c7762e1fdd9c Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/images/popups-border.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/js/ctools-ajax-sample.js b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/js/ctools-ajax-sample.js new file mode 100644 index 0000000000000000000000000000000000000000..0273bc1588838d0d75d8439a4129ff3c7dc3e49b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_ajax_sample/js/ctools-ajax-sample.js @@ -0,0 +1,42 @@ +/** +* Provide the HTML to create the modal dialog. +*/ +Drupal.theme.prototype.CToolsSampleModal = function () { + var html = '' + + html += '<div id="ctools-modal" class="popups-box">'; + html += ' <div class="ctools-modal-content ctools-sample-modal-content">'; + html += ' <table cellpadding="0" cellspacing="0" id="ctools-face-table">'; + html += ' <tr>'; + html += ' <td class="popups-tl popups-border"></td>'; + html += ' <td class="popups-t popups-border"></td>'; + html += ' <td class="popups-tr popups-border"></td>'; + html += ' </tr>'; + html += ' <tr>'; + html += ' <td class="popups-cl popups-border"></td>'; + html += ' <td class="popups-c" valign="top">'; + html += ' <div class="popups-container">'; + html += ' <div class="modal-header popups-title">'; + html += ' <span id="modal-title" class="modal-title"></span>'; + html += ' <span class="popups-close"><a class="close" href="#">' + Drupal.CTools.Modal.currentSettings.closeText + '</a></span>'; + html += ' <div class="clear-block"></div>'; + html += ' </div>'; + html += ' <div class="modal-scroll"><div id="modal-content" class="modal-content popups-body"></div></div>'; + html += ' <div class="popups-buttons"></div>'; //Maybe someday add the option for some specific buttons. + html += ' <div class="popups-footer"></div>'; //Maybe someday add some footer. + html += ' </div>'; + html += ' </td>'; + html += ' <td class="popups-cr popups-border"></td>'; + html += ' </tr>'; + html += ' <tr>'; + html += ' <td class="popups-bl popups-border"></td>'; + html += ' <td class="popups-b popups-border"></td>'; + html += ' <td class="popups-br popups-border"></td>'; + html += ' </tr>'; + html += ' </table>'; + html += ' </div>'; + html += '</div>'; + + return html; + +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.info b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.info new file mode 100644 index 0000000000000000000000000000000000000000..930579c7479940d2786c64c5bc677dfc5a0ef527 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.info @@ -0,0 +1,12 @@ +name = Custom content panes +description = Create custom, exportable, reusable content panes for applications like Panels. +core = 6.x +package = Chaos tool suite +dependencies[] = ctools + +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.install b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.install new file mode 100644 index 0000000000000000000000000000000000000000..738841215ccba96310feeb0b17ff36a26c20881f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.install @@ -0,0 +1,83 @@ +<?php + +/** + * Schema for CTools custom content. + */ +function ctools_custom_content_schema() { + return ctools_custom_content_schema_1(); +} + +function ctools_custom_content_schema_1() { + $schema = array(); + + $schema['ctools_custom_content'] = array( + 'description' => 'Contains exportable customized content for this site.', + 'export' => array( + 'identifier' => 'content', + 'bulk export' => TRUE, + 'primary key' => 'cid', + 'api' => array( + 'owner' => 'ctools', + 'api' => 'ctools_content', + 'minimum_version' => 1, + 'current_version' => 1, + ), + 'create callback' => 'ctools_content_type_new', + ), + 'fields' => array( + 'cid' => array( + 'type' => 'serial', + 'description' => 'A database primary key to ensure uniqueness', + 'not null' => TRUE, + 'no export' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this content. Used to identify it programmatically.', + ), + 'admin_title' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Administrative title for this content.', + ), + 'admin_description' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Administrative description for this content.', + 'object default' => '', + ), + 'category' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Administrative category for this content.', + ), + 'settings' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Serialized settings for the actual content to be used', + 'serialize' => TRUE, + 'object default' => array(), + ), + ), + 'primary key' => array('cid'), + ); + + return $schema; +} + +/** + * Implementation of hook_install(). + */ +function ctools_custom_content_install() { + if (!db_table_exists('ctools_custom_content')) { + drupal_install_schema('ctools_custom_content'); + } +} + +/** + * Implementation of hook_uninstall(). + */ +function ctools_custom_content_uninstall() { + drupal_uninstall_schema('ctools_custom_content'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.module b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.module new file mode 100644 index 0000000000000000000000000000000000000000..31b0bd22e84b7260c7e04ff0194716a334ff122f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/ctools_custom_content.module @@ -0,0 +1,95 @@ +<?php + +/** + * @file + * ctools_custom_content module + * + * This module allows styles to be created and managed on behalf of modules + * that implement styles. + * + * The ctools_custom_content tool allows recolorable styles to be created via a miniature + * scripting language. Panels utilizes this to allow administrators to add + * styles directly to any panel display. + */ + +/** + * Implementation of hook_perm() + */ +function ctools_custom_content_perm() { + return array( + 'administer custom content', + ); +} + +/** + * Implementation of hook_ctools_plugin_directory() to let the system know + * we implement task and task_handler plugins. + */ +function ctools_custom_content_ctools_plugin_directory($module, $plugin) { + // Most of this module is implemented as an export ui plugin, and the + // rest is in ctools/includes/ctools_custom_content.inc + if ($module == 'ctools' && $plugin == 'export_ui') { + return 'plugins/' . $plugin; + } +} + +/** + * Create callback for creating a new CTools custom content type. + * + * This ensures we get proper defaults from the plugin for its settings. + */ +function ctools_content_type_new($set_defaults) { + $item = ctools_export_new_object('ctools_custom_content', $set_defaults); + ctools_include('content'); + $plugin = ctools_get_content_type('custom'); + $item->settings = ctools_content_get_defaults($plugin, array()); + return $item; +} + +/** + * Implementation of hook_panels_dashboard_blocks(). + * + * Adds page information to the Panels dashboard. + */ +function ctools_custom_content_panels_dashboard_blocks(&$vars) { + $vars['links']['ctools_custom_content'] = array( + 'title' => l(t('Custom content'), 'admin/build/ctools-content/add'), + 'description' => t('Custom content panes are basic HTML you enter that can be reused in all of your panels.'), + ); + + // Load all mini panels and their displays. + ctools_include('export'); + $items = ctools_export_crud_load_all('ctools_custom_content'); + $count = 0; + $rows = array(); + + foreach ($items as $item) { + $rows[] = array( + check_plain($item->admin_title), + array( + 'data' => l(t('Edit'), "admin/build/ctools-content/list/$item->name/edit"), + 'class' => 'links', + ), + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + + if ($rows) { + $content = theme('table', array(), $rows, array('class' => 'panels-manage')); + } + else { + $content = '<p>' . t('There are no custom content panes.') . '</p>'; + } + + $vars['blocks']['ctools_custom_content'] = array( + 'title' => t('Manage custom content'), + 'link' => l(t('Go to list'), 'admin/build/ctools-content'), + 'content' => $content, + 'class' => 'dashboard-content', + 'section' => 'right', + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content.inc new file mode 100644 index 0000000000000000000000000000000000000000..7487ead50bb21a40564a4f8a8ca7fed434e0cce3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content.inc @@ -0,0 +1,23 @@ +<?php + +$plugin = array( + 'schema' => 'ctools_custom_content', + 'access' => 'administer custom content', + + 'menu' => array( + 'menu item' => 'ctools-content', + 'menu title' => 'Custom content panes', + 'menu description' => 'Add, edit or delete custom content panes.', + ), + + 'title singular' => t('content pane'), + 'title singular proper' => t('Content pane'), + 'title plural' => t('content panes'), + 'title plural proper' => t('Content panes'), + + 'handler' => array( + 'class' => 'ctools_custom_content_ui', + 'parent' => 'ctools_export_ui', + ), +); + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content_ui.class.php b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..221de05b8041bfc323c410fb378d4fa101c899ad --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content_ui.class.php @@ -0,0 +1,123 @@ +<?php + +class ctools_custom_content_ui extends ctools_export_ui { + + function edit_form(&$form, &$form_state) { + parent::edit_form($form, $form_state); + + $form['category'] = array( + '#type' => 'textfield', + '#title' => t('Category'), + '#description' => t('What category this content should appear in. If left blank the category will be "Miscellaneous".'), + '#default_value' => $form_state['item']->category, + ); + + $form['title'] = array( + '#type' => 'textfield', + '#default_value' => $form_state['item']->settings['title'], + '#title' => t('Title'), + ); + + $form['body_field']['body'] = array( + '#title' => t('Body'), + '#type' => 'textarea', + '#default_value' => $form_state['item']->settings['body'], + ); + $parents[] = 'format'; + $form['body_field']['format'] = filter_form($form_state['item']->settings['format'], 1, $parents); + + $form['substitute'] = array( + '#type' => 'checkbox', + '#title' => t('Use context keywords'), + '#description' => t('If checked, context keywords will be substituted in this content.'), + '#default_value' => !empty($form_state['item']->settings['substitute']), + ); + } + + function edit_form_submit(&$form, &$form_state) { + parent::edit_form_submit($form, $form_state); + + // Since items in our settings are not in the schema, we have to do these manually: + $form_state['item']->settings['title'] = $form_state['values']['title']; + $form_state['item']->settings['body'] = $form_state['values']['body']; + $form_state['item']->settings['format'] = $form_state['values']['format']; + $form_state['item']->settings['substitute'] = $form_state['values']['substitute']; + } + + function list_form(&$form, &$form_state) { + parent::list_form($form, $form_state); + + $options = array('all' => t('- All -')); + foreach ($this->items as $item) { + $options[$item->category] = $item->category; + } + + $form['top row']['category'] = array( + '#type' => 'select', + '#title' => t('Category'), + '#options' => $options, + '#default_value' => 'all', + '#weight' => -10, + ); + } + + function list_filter($form_state, $item) { + if ($form_state['values']['category'] != 'all' && $form_state['values']['category'] != $item->category) { + return TRUE; + } + + return parent::list_filter($form_state, $item); + } + + function list_sort_options() { + return array( + 'disabled' => t('Enabled, title'), + 'title' => t('Title'), + 'name' => t('Name'), + 'category' => t('Category'), + 'storage' => t('Storage'), + ); + } + + function list_build_row($item, &$form_state, $operations) { + // Set up sorting + switch ($form_state['values']['order']) { + case 'disabled': + $this->sorts[$item->name] = empty($item->disabled) . $item->admin_title; + break; + case 'title': + $this->sorts[$item->name] = $item->admin_title; + break; + case 'name': + $this->sorts[$item->name] = $item->name; + break; + case 'category': + $this->sorts[$item->name] = $item->category; + break; + case 'storage': + $this->sorts[$item->name] = $item->type . $item->admin_title; + break; + } + + $this->rows[$item->name] = array( + 'data' => array( + array('data' => check_plain($item->name), 'class' => 'ctools-export-ui-name'), + array('data' => check_plain($item->admin_title), 'class' => 'ctools-export-ui-title'), + array('data' => check_plain($item->category), 'class' => 'ctools-export-ui-category'), + array('data' => theme('links', $operations), 'class' => 'ctools-export-ui-operations'), + ), + 'title' => check_plain($item->admin_description), + 'class' => !empty($item->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled', + ); + } + + function list_table_header() { + return array( + array('data' => t('Name'), 'class' => 'ctools-export-ui-name'), + array('data' => t('Title'), 'class' => 'ctools-export-ui-title'), + array('data' => t('Category'), 'class' => 'ctools-export-ui-category'), + array('data' => t('Operations'), 'class' => 'ctools-export-ui-operations'), + ); + } + +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/README.txt b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..42edcdc9025c3c28d542fde5e07e4b77fdeee618 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/README.txt @@ -0,0 +1,14 @@ + +The CTools Plugin Example is an example for developers of how to CTools +access, argument, content type, context, and relationship plugins. + +There are a number of ways to profit from this: + +1. The code itself intends to be as simple and self-explanatory as possible. + Nothing fancy is attempted: It's just trying to use the plugin API to show + how it can be used. + +2. There is a sample panel. You can access it at /ctools_plugin_example/xxxx + to see how it works. + +3. There is Advanced Help at admin/advanced_help/ctools_plugin_example. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.info b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.info new file mode 100644 index 0000000000000000000000000000000000000000..675a779ce98e44c96f11463d90a3bc347950bd9f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.info @@ -0,0 +1,15 @@ +name = Chaos Tools (CTools) Plugin Example +description = Shows how an external module can provide ctools plugins (for Panels, etc.). +package = Chaos tool suite +dependencies[] = ctools +dependencies[] = panels +dependencies[] = page_manager +dependencies[] = advanced_help +core = 6.x + +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.module b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.module new file mode 100644 index 0000000000000000000000000000000000000000..060488d1fa4691153415dea871d23cb52a6a8daf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.module @@ -0,0 +1,94 @@ +<?php + +/* + * @file + * + * Working sample module to demonstrate CTools 3 plugins + * + * This sample module is only intended to demonstrate how external modules can + * provide ctools plugins. There is no useful functionality, and it's only + * intended for developers or for educational use. + * + * As far as possible, everything is kept very simple, not exercising all of + * the capabilities of CTools or Panels. + * + * Although the ctools documentation suggests that strict naming conventions + * be followed, this code attempts to follow only the conventions which are + * required (the hooks), in order to demonstrate the difference. You can + * certainly use the conventions, but it's important to know the difference + * between a convention and a requirement. + * + * The advanced_help module is required, because both CTools and this module + * provide help that way. + * + * There is a demonstration panel provided at /ctools_plugin_example/123 + */ + +/** + * Implementation of hook_menu + */ +function ctools_plugin_example_menu() { + $items = array(); + + $items["admin/settings/ctools_plugin_example"] = array( + 'title' => 'CTools plugin example', + 'description' => t("Demonstration code, advanced help, and a demo panel to show how to build ctools plugins."), + 'page callback' => 'ctools_plugin_example_explanation_page', + 'access arguments' => array('administer site configuration'), + 'type' => MENU_NORMAL_ITEM, + ); + + return $items; +} + +/** + * Implementation of hook_ctools_plugin_directory(). + * + * It simply tells panels where to find the .inc files that define various + * args, contexts, content_types. In this case the subdirectories of + * ctools_plugin_example/panels are used. + */ +function ctools_plugin_example_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && !empty($plugin)) { + return "plugins/$plugin"; + } +} + +/** + * Implement hook_ctools_plugin_api(). + * + * If you do this, CTools will pick up default panels pages in + * <modulename>.pages_default.inc + */ +function ctools_plugin_example_ctools_plugin_api($module, $api) { + // @todo -- this example should explain how to put it in a different file. + if ($module == 'panels_mini' && $api == 'panels_default') { + return array('version' => 1); + } + if ($module == 'page_manager' && $api == 'pages_default') { + return array('version' => 1); + } +} + +/** + * Just provide an explanation page for the admin section + * @return unknown_type + */ +function ctools_plugin_example_explanation_page() { + $content = '<p>' . t("The CTools Plugin Example is simply a developer's demo of how to create plugins for CTools. It provides no useful functionality for an ordinary user.") . '</p>'; + + $content .= '<p>' . t( + 'There is a demo panel demonstrating much of the functionality provided at + <a href="@demo_url">CTools demo panel</a>, and you can find documentation on the examples at + !ctools_plugin_example_help. + CTools itself provides documentation at !ctools_help. Mostly, though, the code itself is intended to be the teacher. + You can find it in %path.', + array( + '@demo_url' => url('ctools_plugin_example/xxxxx'), + '!ctools_plugin_example_help' => theme('advanced_help_topic', 'ctools_plugin_example', 'Chaos-Tools--CTools--Plugin-Examples', 'title'), + '!ctools_help' => theme('advanced_help_topic', 'ctools', 'plugins', 'title'), + '%path' => drupal_get_path('module', 'ctools_plugin_example'), + )) . '</p>'; + + return $content; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.pages_default.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.pages_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..10a76193826443f20dce69dd6b5a0275033223cd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/ctools_plugin_example.pages_default.inc @@ -0,0 +1,451 @@ +<?php + +/** + * @file + * This module provides default panels to demonstrate the behavior of the plugins. + */ + +/** + * Default panels pages for CTools Plugin Example + * + * To pick up this file, your module needs to implement + * hook_ctools_plugin_api() - See ctools_plugin_example_ctools_plugin_api() in + * ctools_plugin_example.module. + * + * + * Note the naming of the file: <modulename>.pages_default.inc + * With this naming, no additional code needs to be provided. CTools will just find the file. + * The name of the hook is <modulename>_default_page_manager_pages() + * + * This example provides two pages, but the returned array could + * have several pages. + * + * @return + * Array of pages, normally exported from Panels. + */ + +function ctools_plugin_example_default_page_manager_pages() { + + // begin exported panel. + + $page = new stdClass; + $page->disabled = FALSE; /* Edit this to true to make a default page disabled initially */ + $page->api_version = 1; + $page->name = 'ctools_plugin_example'; + $page->task = 'page'; + $page->admin_title = 'CTools plugin example'; + $page->admin_description = 'This panel provides no functionality to a working Drupal system. It\'s intended to display the various sample plugins provided by the CTools Plugin Example module. '; + $page->path = 'ctools_plugin_example/%sc'; + $page->access = array( + 'logic' => 'and', + ); + $page->menu = array( + 'type' => 'normal', + 'title' => 'CTools plugin example', + 'name' => 'navigation', + 'weight' => '0', + 'parent' => array( + 'type' => 'none', + 'title' => '', + 'name' => 'navigation', + 'weight' => '0', + ), + ); + $page->arguments = array( + 'sc' => array( + 'id' => 2, + 'identifier' => 'simplecontext-arg', + 'name' => 'simplecontext_arg', + 'settings' => array(), + ), + ); + $page->conf = array(); + $page->default_handlers = array(); + $handler = new stdClass; + $handler->disabled = FALSE; /* Edit this to true to make a default handler disabled initially */ + $handler->api_version = 1; + $handler->name = 'page_ctools_panel_context'; + $handler->task = 'page'; + $handler->subtask = 'ctools_plugin_example'; + $handler->handler = 'panel_context'; + $handler->weight = 0; + $handler->conf = array( + 'title' => 'Panel', + 'no_blocks' => FALSE, + 'css_id' => '', + 'css' => '', + 'contexts' => array( + '0' => array( + 'name' => 'simplecontext', + 'id' => 1, + 'identifier' => 'Configured simplecontext (not from argument)', + 'keyword' => 'configured_simplecontext', + 'context_settings' => array( + 'sample_simplecontext_setting' => 'default simplecontext setting', + ), + ), + ), + 'relationships' => array( + '0' => array( + 'context' => 'argument_simplecontext_arg_2', + 'name' => 'relcontext_from_simplecontext', + 'id' => 1, + 'identifier' => 'Relcontext from simplecontext (from relationship)', + 'keyword' => 'relcontext', + ), + ), + 'access' => array( + 'logic' => 'and', + ), + ); + $display = new panels_display; + $display->layout = 'threecol_33_34_33_stacked'; + $display->layout_settings = array(); + $display->panel_settings = array( + 'style' => 'rounded_corners', + 'style_settings' => array( + 'default' => array( + 'corner_location' => 'pane', + ), + ), + ); + $display->cache = array(); + $display->title = 'CTools plugin example panel'; + $display->hide_title = FALSE; + $display->title_pane = 1; + $display->content = array(); + $display->panels = array(); + $pane = new stdClass; + $pane->pid = 'new-1'; + $pane->panel = 'left'; + $pane->type = 'no_context_content_type'; + $pane->subtype = 'no_context_content_type'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'item1' => 'contents of config item 1', + 'item2' => 'contents of config item 2', + 'override_title' => 0, + 'override_title_text' => '', + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-1'] = $pane; + $display->panels['left'][0] = 'new-1'; + $pane = new stdClass; + $pane->pid = 'new-2'; + $pane->panel = 'left'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array( + 'plugins' => array( + '0' => array( + 'name' => 'arg_length', + 'settings' => array( + 'greater_than' => '1', + 'arg_length' => '4', + ), + 'context' => 'argument_simplecontext_arg_2', + ), + ), + ); + $pane->configuration = array( + 'title' => 'Long Arg Visibility Block', + 'body' => 'This block will be here when the argument is longer than configured arg length. It uses the \'arg_length\' access plugin to test against the length of the argument used for Simplecontext.', + 'format' => '1', + 'substitute' => 1, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 1; + $display->content['new-2'] = $pane; + $display->panels['left'][1] = 'new-2'; + $pane = new stdClass; + $pane->pid = 'new-3'; + $pane->panel = 'left'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array( + 'plugins' => array( + '0' => array( + 'name' => 'arg_length', + 'settings' => array( + 'greater_than' => '0', + 'arg_length' => '4', + ), + 'context' => 'argument_simplecontext_arg_2', + ), + ), + ); + $pane->configuration = array( + 'title' => 'Short Arg Visibility', + 'body' => 'This block appears when the simplecontext argument is <i>less than</i> the configured length.', + 'format' => '1', + 'substitute' => 1, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 2; + $display->content['new-3'] = $pane; + $display->panels['left'][2] = 'new-3'; + $pane = new stdClass; + $pane->pid = 'new-4'; + $pane->panel = 'middle'; + $pane->type = 'simplecontext_content_type'; + $pane->subtype = 'simplecontext_content_type'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'buttons' => NULL, + '#validate' => NULL, + '#submit' => NULL, + '#action' => NULL, + 'context' => 'argument_simplecontext_arg_2', + 'aligner_start' => NULL, + 'override_title' => 1, + 'override_title_text' => 'Simplecontext (with an arg)', + 'aligner_stop' => NULL, + 'override_title_markup' => NULL, + 'config_item_1' => 'Config item 1 contents', + '#build_id' => NULL, + '#type' => NULL, + '#programmed' => NULL, + 'form_build_id' => 'form-19c4ae6cb54fad8f096da46e95694e5a', + '#token' => NULL, + 'form_token' => '17141d3531eaa7b609da78afa6f3b560', + 'form_id' => 'simplecontext_content_type_edit_form', + '#id' => NULL, + '#description' => NULL, + '#attributes' => NULL, + '#required' => NULL, + '#tree' => NULL, + '#parents' => NULL, + '#method' => NULL, + '#post' => NULL, + '#processed' => NULL, + '#defaults_loaded' => NULL, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-4'] = $pane; + $display->panels['middle'][0] = 'new-4'; + $pane = new stdClass; + $pane->pid = 'new-5'; + $pane->panel = 'middle'; + $pane->type = 'simplecontext_content_type'; + $pane->subtype = 'simplecontext_content_type'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'buttons' => NULL, + '#validate' => NULL, + '#submit' => NULL, + '#action' => NULL, + 'context' => 'context_simplecontext_1', + 'aligner_start' => NULL, + 'override_title' => 1, + 'override_title_text' => 'Configured simplecontext content type (not from arg)', + 'aligner_stop' => NULL, + 'override_title_markup' => NULL, + 'config_item_1' => '(configuration for simplecontext)', + '#build_id' => NULL, + '#type' => NULL, + '#programmed' => NULL, + 'form_build_id' => 'form-d016200490abd015dc5b8a7e366d76ea', + '#token' => NULL, + 'form_token' => '17141d3531eaa7b609da78afa6f3b560', + 'form_id' => 'simplecontext_content_type_edit_form', + '#id' => NULL, + '#description' => NULL, + '#attributes' => NULL, + '#required' => NULL, + '#tree' => NULL, + '#parents' => NULL, + '#method' => NULL, + '#post' => NULL, + '#processed' => NULL, + '#defaults_loaded' => NULL, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 1; + $display->content['new-5'] = $pane; + $display->panels['middle'][1] = 'new-5'; + $pane = new stdClass; + $pane->pid = 'new-6'; + $pane->panel = 'middle'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'admin_title' => 'Simplecontext keyword usage', + 'title' => 'Simplecontext keyword usage', + 'body' => 'Demonstrating context keyword usage: + item1 is %sc:item1 + item2 is %sc:item2 + description is %sc:description', + 'format' => '1', + 'substitute' => 1, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 2; + $display->content['new-6'] = $pane; + $display->panels['middle'][2] = 'new-6'; + $pane = new stdClass; + $pane->pid = 'new-7'; + $pane->panel = 'right'; + $pane->type = 'relcontext_content_type'; + $pane->subtype = 'relcontext_content_type'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'buttons' => NULL, + '#validate' => NULL, + '#submit' => NULL, + '#action' => NULL, + 'context' => 'relationship_relcontext_from_simplecontext_1', + 'aligner_start' => NULL, + 'override_title' => 0, + 'override_title_text' => '', + 'aligner_stop' => NULL, + 'override_title_markup' => NULL, + 'config_item_1' => 'some stuff in this one', + '#build_id' => NULL, + '#type' => NULL, + '#programmed' => NULL, + 'form_build_id' => 'form-8485f84511bd06e51b4a48e998448054', + '#token' => NULL, + 'form_token' => '1c3356396374d51d7d2531a10fd25310', + 'form_id' => 'relcontext_edit_form', + '#id' => NULL, + '#description' => NULL, + '#attributes' => NULL, + '#required' => NULL, + '#tree' => NULL, + '#parents' => NULL, + '#method' => NULL, + '#post' => NULL, + '#processed' => NULL, + '#defaults_loaded' => NULL, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-7'] = $pane; + $display->panels['right'][0] = 'new-7'; + $pane = new stdClass; + $pane->pid = 'new-8'; + $pane->panel = 'top'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'title' => 'Demonstrating ctools plugins', + 'body' => 'The CTools Plugin Example module (and this panel page) are just here to demonstrate how to build CTools plugins. + + ', + 'format' => '2', + 'substitute' => 1, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-8'] = $pane; + $display->panels['top'][0] = 'new-8'; + $handler->conf['display'] = $display; + $page->default_handlers[$handler->name] = $handler; + + // end of exported panel. + $pages['ctools_plugin_example_demo_page'] = $page; + + // begin exported panel + + $page = new stdClass; + $page->disabled = FALSE; /* Edit this to true to make a default page disabled initially */ + $page->api_version = 1; + $page->name = 'ctools_plugin_example_base'; + $page->task = 'page'; + $page->admin_title = 'CTools Plugin Example base page'; + $page->admin_description = 'This panel is for when people hit /ctools_plugin_example without an argument. We can use it to tell people to move on.'; + $page->path = 'ctools_plugin_example'; + $page->access = array(); + $page->menu = array(); + $page->arguments = array(); + $page->conf = array(); + $page->default_handlers = array(); + $handler = new stdClass; + $handler->disabled = FALSE; /* Edit this to true to make a default handler disabled initially */ + $handler->api_version = 1; + $handler->name = 'page_ctools_plugin_example_base_panel_context'; + $handler->task = 'page'; + $handler->subtask = 'ctools_plugin_example_base'; + $handler->handler = 'panel_context'; + $handler->weight = 0; + $handler->conf = array( + 'title' => 'Panel', + 'no_blocks' => FALSE, + 'css_id' => '', + 'css' => '', + 'contexts' => array(), + 'relationships' => array(), + ); + $display = new panels_display; + $display->layout = 'onecol'; + $display->layout_settings = array(); + $display->panel_settings = array(); + $display->cache = array(); + $display->title = ''; + $display->hide_title = FALSE; + $display->content = array(); + $display->panels = array(); + $pane = new stdClass; + $pane->pid = 'new-1'; + $pane->panel = 'middle'; + $pane->type = 'custom'; + $pane->subtype = 'custom'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'title' => 'Use this page with an argument', + 'body' => 'This demo page works if you use an argument, like <a href="ctools_plugin_example/xxxxx">ctools_plugin_example/xxxxx</a>.', + 'format' => '1', + 'substitute' => NULL, + ); + $pane->cache = array(); + $pane->style = array(); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $display->content['new-1'] = $pane; + $display->panels['middle'][0] = 'new-1'; + $handler->conf['display'] = $display; + $page->default_handlers[$handler->name] = $handler; + // end exported panel. + + $pages['base_page'] = $page; + + return $pages; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Access-Plugins--Determining-access-and-visibility.html b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Access-Plugins--Determining-access-and-visibility.html new file mode 100644 index 0000000000000000000000000000000000000000..781260ed1cd942a4836742e782a8ce3d32bed499 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Access-Plugins--Determining-access-and-visibility.html @@ -0,0 +1,17 @@ +<div id="node-16" class="node"> + + + + + <div class="content clear-block"> + <p>We can use access plugins to determine access to a page or visibility of the panes in a page. Basically, we just determine access based on configuration settings and the various contexts that are available to us.</p> +<p>The arbitrary example in plugins/access/arg_length.inc determines access based on the length of the simplecontext argument. You can configure whether access should be granted if the simplecontext argument is greater or less than some number.</p> + </div> + + <div class="clear-block"> + <div class="meta"> + </div> + + </div> + +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Argument-Plugins--Starting-at-the-beginning.html b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Argument-Plugins--Starting-at-the-beginning.html new file mode 100644 index 0000000000000000000000000000000000000000..4dd569d7114f504b6774efadcdf2cb2e5b02b5ab --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Argument-Plugins--Starting-at-the-beginning.html @@ -0,0 +1,20 @@ +<div id="node-12" class="node"> + + + + + <div class="content clear-block"> + <p>Contexts are fundamental to CTools, and they almost always start with an argument to a panels page, so we'll start there too.</p> +<p>We first need to process an argument.</p> +<p>We're going to work with a "Simplecontext" context type and argument, and then with a content type that displays it. So we'll start by with the Simplecontext argument plugin in plugins/arguments/simplecontext_arg.inc.</p> +<p>Note that the name of the file (simplecontext_arg.inc) is built from the machine name of our plugin (simplecontext_arg). And note also that the primary function that we use to provide our argument (ctools_plugin_example_simplecontext_arg_ctools_arguments()) is also built from the machine name. This magic is most of the naming magic that you have to know.</p> +<p>You can browse plugins/arguments/simplecontext_arg.inc and see the little that it does.</p> + </div> + + <div class="clear-block"> + <div class="meta"> + </div> + + </div> + +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Chaos-Tools--CTools--Plugin-Examples.html b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Chaos-Tools--CTools--Plugin-Examples.html new file mode 100644 index 0000000000000000000000000000000000000000..7576c80bc55959f9a83fe183b6c79b3ae8a51f22 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Chaos-Tools--CTools--Plugin-Examples.html @@ -0,0 +1,19 @@ +<div id="node-10" class="node"> + + + + + <div class="content clear-block"> + <p>This demonstration module is intended for developers to look at and play with. CTools plugins are not terribly difficult to do, but it can be hard to sort through the various arguments and required functions. The idea here is that you should have a starting point for most anything you want to do. Just work through the example, and then start experimenting with changing it.</p> +<p>There are two parts to this demo: </p> +<p>First, there is a sample panel provided that uses all the various plugins. It's at <a href="/ctools_plugin_example/12345">ctools_example/12345</a>. You can edit the panel and configure all the panes on it.</p> +<p>Second, the code is there for you to experiment with and change as you see fit. Sometimes starting with simple code and working with it can take you places that it's hard to go when you're looking at more complex examples.</p> + </div> + + <div class="clear-block"> + <div class="meta"> + </div> + + </div> + +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Content-Type-Plugins--Displaying-content-using-a-context.html b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Content-Type-Plugins--Displaying-content-using-a-context.html new file mode 100644 index 0000000000000000000000000000000000000000..918a13cb83170a2191a9c99bddff16badc6788ec --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Content-Type-Plugins--Displaying-content-using-a-context.html @@ -0,0 +1,17 @@ +<div id="node-14" class="node"> + + + + + <div class="content clear-block"> + <p>Now we get to the heart of the matter: Building a content type plugin. A content type plugin uses the contexts available to it to display something. plugins/content_types/simplecontext_content_type.inc does this work for us.</p> +<p>Note that our content type also has an edit form which can be used to configure its behavior. This settings form is accessed through the panels interface, and it's up to you what the settings mean to the code and the generation of content in the display rendering.</p> + </div> + + <div class="clear-block"> + <div class="meta"> + </div> + + </div> + +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Context-plugins--Creating-a--context--from-an-argument.html b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Context-plugins--Creating-a--context--from-an-argument.html new file mode 100644 index 0000000000000000000000000000000000000000..e8efbb3908de50431af06e99c685eaea3c8fdc87 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Context-plugins--Creating-a--context--from-an-argument.html @@ -0,0 +1,21 @@ +<div id="node-13" class="node"> + + + + + <div class="content clear-block"> + <p>Now that we have a plugin for a simplecontext argument, we can create a plugin for a simplecontext context. </p> +<p>Normally, a context would take an argument which is a key like a node ID (nid) and retrieve a more complex object from a database or whatever. In our example, we'll artificially transform the argument into an arbitrary "context" data object. </p> +<p>plugins/contexts/simplecontext.inc implements our context.</p> +<p>Note that there are actually two ways to create a context. The normal one, which we've been referring to, is to create a context from an argument. However, it is also possible to configure a context in a panel using the panels interface. This is quite inflexible, but might be useful for configuring single page. However, it means that we have a settings form for exactly that purpose. Our context would have to know how to create itself from a settings form as well as from an argument. Simplecontext can do that.</p> +<p>A context plugin can also provide keywords that expose parts of its context using keywords like masterkeyword:dataitem. The node plugin for ctools has node:nid and node:title, for example. The simplecontext plugin here provides the simplest of keywords.</p> + + </div> + + <div class="clear-block"> + <div class="meta"> + </div> + + </div> + +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Module-setup-and-hooks.html b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Module-setup-and-hooks.html new file mode 100644 index 0000000000000000000000000000000000000000..f816917dd1747a452143485f91efd19252400b42 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Module-setup-and-hooks.html @@ -0,0 +1,20 @@ +<div id="node-11" class="node"> + + + + + <div class="content clear-block"> + <p>Your module must provide a few things so that your plugins can be found.</p> +<p>First, you need to implement hook_ctools_plugin_directory(). Here we're telling CTools that our plugins will be found in the module's directory in the plugins/<plugintype> directory. Context plugins will be in ctools_plugin_example/plugins/contexts, Content-type plugins will be in ctools_plugin_example/plugins/content_types.</p> +<p><div class="codeblock"><code><span style="color: #000000"><span style="color: #0000BB"><?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">ctools_plugin_example_ctools_plugin_directory</span><span style="color: #007700">(</span><span style="color: #0000BB">$module</span><span style="color: #007700">, </span><span style="color: #0000BB">$plugin</span><span style="color: #007700">) {<br /> if (</span><span style="color: #0000BB">$module </span><span style="color: #007700">== </span><span style="color: #DD0000">'ctools' </span><span style="color: #007700">&& !empty(</span><span style="color: #0000BB">$plugin</span><span style="color: #007700">)) {<br /> return </span><span style="color: #DD0000">"plugins/$plugin"</span><span style="color: #007700">;<br /> }<br />}<br /></span><span style="color: #0000BB">?></span></span></code></div></p> +<p>Second, if you module wants to provide default panels pages, you can implement hook_ctools_plugin_api(). CTools will then pick up your panels pages in the file named <modulename>.pages_default.inc.</p> +<p><div class="codeblock"><code><span style="color: #000000"><span style="color: #0000BB"><?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">ctools_plugin_example_ctools_plugin_api</span><span style="color: #007700">(</span><span style="color: #0000BB">$module</span><span style="color: #007700">, </span><span style="color: #0000BB">$api</span><span style="color: #007700">) {<br /> if (</span><span style="color: #0000BB">$module </span><span style="color: #007700">== </span><span style="color: #DD0000">'panels_mini' </span><span style="color: #007700">&& </span><span style="color: #0000BB">$api </span><span style="color: #007700">== </span><span style="color: #DD0000">'panels_default'</span><span style="color: #007700">) {<br /> return array(</span><span style="color: #DD0000">'version' </span><span style="color: #007700">=> </span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /> }<br /> if (</span><span style="color: #0000BB">$module </span><span style="color: #007700">== </span><span style="color: #DD0000">'page_manager' </span><span style="color: #007700">&& </span><span style="color: #0000BB">$api </span><span style="color: #007700">== </span><span style="color: #DD0000">'pages_default'</span><span style="color: #007700">) {<br /> return array(</span><span style="color: #DD0000">'version' </span><span style="color: #007700">=> </span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /> }<br />}<br /></span><span style="color: #0000BB">?></span></span></code></div></p> + </div> + + <div class="clear-block"> + <div class="meta"> + </div> + + </div> + +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Relationships--Letting-one-context-take-us-to-another.html b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Relationships--Letting-one-context-take-us-to-another.html new file mode 100644 index 0000000000000000000000000000000000000000..7691245adb5345691ce093339171103dade288c6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/Relationships--Letting-one-context-take-us-to-another.html @@ -0,0 +1,18 @@ +<div id="node-15" class="node"> + + + + + <div class="content clear-block"> + <p>Often a single data type can lead us to other data types. For example, a node has a user (the author) and the user has data associated with it.</p> +<p>A relationship plugin allows this kind of data to be accessed. </p> +<p>An example relationship plugin is provided in plugins/relationships/relcontext_from_simplecontext.inc. It looks at a simplecontext (which we got from an argument) and builds an (artificial) "relcontext" from that.</p> + </div> + + <div class="clear-block"> + <div class="meta"> + </div> + + </div> + +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/ctools_plugin_example.help.ini b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/ctools_plugin_example.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..6fb3d4c0829b007acf32b3d9a6f3ae8f3cc68718 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/help/ctools_plugin_example.help.ini @@ -0,0 +1,42 @@ +[Chaos-Tools--CTools--Plugin-Examples] +title = CTools Plugin Examples +file = Chaos-Tools--CTools--Plugin-Examples +weight = 0 +parent = + +[Module-setup-and-hooks] +title = Module setup and hooks +file = Module-setup-and-hooks +weight = -15 +parent = Chaos-Tools--CTools--Plugin-Examples + +[Argument-Plugins--Starting-at-the-beginning] +title = Argument Plugins: Starting at the beginning +file = Argument-Plugins--Starting-at-the-beginning +weight = -14 +parent = Chaos-Tools--CTools--Plugin-Examples + +[Context-plugins--Creating-a--context--from-an-argument] +title = Context plugins: Creating a context from an argument +file = Context-plugins--Creating-a--context--from-an-argument +weight = -13 +parent = Chaos-Tools--CTools--Plugin-Examples + +[Content-Type-Plugins--Displaying-content-using-a-context] +title = Content Type Plugins: Displaying content using a context +file = Content-Type-Plugins--Displaying-content-using-a-context +weight = -12 +parent = Chaos-Tools--CTools--Plugin-Examples + +[Access-Plugins--Determining-access-and-visibility] +title = Access Plugins: Determining access and visibility +file = Access-Plugins--Determining-access-and-visibility +weight = -11 +parent = Chaos-Tools--CTools--Plugin-Examples + +[Relationships--Letting-one-context-take-us-to-another] +title = Relationships: Letting one context take us to another +file = Relationships--Letting-one-context-take-us-to-another +weight = -10 +parent = Chaos-Tools--CTools--Plugin-Examples + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/access/arg_length.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/access/arg_length.inc new file mode 100644 index 0000000000000000000000000000000000000000..2a09eea127d6f75d8f9ef7bffcc96f95fbd49e16 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/access/arg_length.inc @@ -0,0 +1,65 @@ +<?php + +/** + * @file + * Plugin to provide access control/visibility based on length of + * simplecontext argument (in URL). + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Arg length"), + 'description' => t('Control access by length of simplecontext argument.'), + 'callback' => 'ctools_plugin_example_arg_length_ctools_access_check', + 'settings form' => 'ctools_plugin_example_arg_length_ctools_access_settings', + 'summary' => 'ctools_plugin_example_arg_length_ctools_access_summary', + 'required context' => new ctools_context_required(t('Simplecontext'), 'simplecontext'), +); + +/** + * Settings form for the 'by role' access plugin. + */ +function ctools_plugin_example_arg_length_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['greater_than'] = array( + '#type' => 'radios', + '#title' => t('Grant access if simplecontext argument length is'), + '#options' => array(1 => t('Greater than'), 0 => t('Less than or equal to')), + '#default_value' => $conf['greater_than'], + ); + $form['settings']['arg_length'] = array( + '#type' => 'textfield', + '#title' => t('Length of simplecontext argument'), + '#size' => 3, + '#default_value' => $conf['arg_length'], + '#description' => t('Access/visibility will be granted based on arg length.'), + ); +} + +/** + * Check for access. + */ +function ctools_plugin_example_arg_length_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data)) { + return FALSE; + } + $compare = ($context->arg_length > $conf['arg_length']); + if (($compare && $conf['greater_than']) || (!$compare && !$conf['greater_than'])) { + return TRUE; + } + return FALSE; +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_plugin_example_arg_length_ctools_access_summary($conf, $context) { + return t('Simpletext argument must be !comp @length characters', + array('!comp' => $conf['greater_than'] ? 'greater than' : 'less than or equal to', + '@length' => $conf['arg_length'])); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/access/example_role.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/access/example_role.inc new file mode 100644 index 0000000000000000000000000000000000000000..bbe364c153d8865e85378a391924b416be82b4b6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/access/example_role.inc @@ -0,0 +1,76 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon role membership. + * This is directly from the ctools module, but serves as a good + * example of an access plugin + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("CTools example: role"), + 'description' => t('Control access by role.'), + 'callback' => 'ctools_plugin_example_example_role_ctools_access_check', + 'default' => array('rids' => array()), + 'settings form' => 'ctools_plugin_example_example_role_ctools_access_settings', + 'summary' => 'ctools_plugin_example_example_role_ctools_access_summary', + 'required context' => new ctools_context_required(t('User'), 'user'), +); + +/** + * Settings form for the 'by role' access plugin. + */ +function ctools_plugin_example_example_role_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['rids'] = array( + '#type' => 'checkboxes', + '#title' => t('Role'), + '#default_value' => $conf['rids'], + '#options' => ctools_get_roles(), + '#description' => t('Only the checked roles will be granted access.'), + ); +} + +/** + * Compress the roles allowed to the minimum. + */ +function ctools_plugin_example_example_role_ctools_access_settings_submit(&$form, &$form_state) { + $form_state['values']['settings']['rids'] = array_keys(array_filter($form_state['values']['settings']['rids'])); +} + +/** + * Check for access. + */ +function ctools_plugin_example_example_role_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data) || !isset($context->data->roles)) { + return FALSE; + } + + $roles = array_keys($context->data->roles); + $roles[] = $context->data->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID; + return (bool) array_intersect($conf['rids'], $roles); +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_plugin_example_example_role_ctools_access_summary($conf, $context) { + if (!isset($conf['rids'])) { + $conf['rids'] = array(); + } + $roles = ctools_get_roles(); + $names = array(); + foreach (array_filter($conf['rids']) as $rid) { + $names[] = check_plain($roles[$rid]); + } + if (empty($names)) { + return t('@identifier can have any role', array('@identifier' => $context->identifier)); + } + return format_plural(count($names), '@identifier must have role "@roles"', '@identifier can be one of "@roles"', array('@roles' => implode(', ', $names), '@identifier' => $context->identifier)); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/arguments/simplecontext_arg.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/arguments/simplecontext_arg.inc new file mode 100644 index 0000000000000000000000000000000000000000..51c7c601c99984998f961cff50d6ba749a4beae7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/arguments/simplecontext_arg.inc @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * + * Sample plugin to provide an argument handler for a simplecontext. + * + * Given any argument to the page, simplecontext will get it + * and turn it into a piece of data (a "context") just by adding some text to it. + * Normally, the argument would be a key into some database (like the node + * database, for example, and the result of using the argument would be to load + * a specific "context" or data item that we can use elsewhere. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Simplecontext arg"), + // keyword to use for %substitution + 'keyword' => 'simplecontext', + 'description' => t('Creates a "simplecontext" from the arg.'), + 'context' => 'simplecontext_arg_context', + // 'settings form' => 'simplecontext_arg_settings_form', + + // placeholder_form is used in panels preview, for example, so we can + // preview without getting the arg from a URL + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the simplecontext arg'), + ), +); + +/** + * Get the simplecontext context using the arg. In this case we're just going + * to manufacture the context from the data in the arg, but normally it would + * be an API call, db lookup, etc. + */ +function simplecontext_arg_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If $empty == TRUE it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('simplecontext'); + } + // Do whatever error checking is required, returning FALSE if it fails the test + // Normally you'd check + // for a missing object, one you couldn't create, etc. + if (empty($arg)) { + return FALSE; + } + return ctools_context_create('simplecontext', $arg); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/icon_example.png b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/icon_example.png new file mode 100644 index 0000000000000000000000000000000000000000..58c6bee4fde937b4f09ca13cfdf2d90d49cdad64 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/icon_example.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/no_context_content_type.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/no_context_content_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..28d749b19586ea325e479d50b1e6b9e2887bd6af --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/no_context_content_type.inc @@ -0,0 +1,116 @@ +<?php + +/** + * @file + * "No context" sample content type. It operates with no context at all. It would + * be basically the same as a 'custom content' block, but it's not even that + * sophisticated. + * + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('CTools example no context content type'), + 'description' => t('No context content type - requires and uses no context.'), + + // 'single' => TRUE means has no subtypes. + 'single' => TRUE, + // Constructor. + 'content_types' => array('no_context_content_type'), + // Name of a function which will render the block. + 'render callback' => 'no_context_content_type_render', + // The default context. + 'defaults' => array(), + + // This explicitly declares the config form. Without this line, the func would be + // ctools_plugin_example_no_context_content_type_edit_form. + 'edit form' => 'no_context_content_type_edit_form', + + // Icon goes in the directory with the content type. + 'icon' => 'icon_example.png', + 'category' => array(t('CTools Examples'), -9), + + // this example does not provide 'admin info', which would populate the + // panels builder page preview. +); + +/** + * Run-time rendering of the body of the block. + * + * @param $subtype + * @param $conf + * Configuration as done at admin time. + * @param $args + * @param $context + * Context - in this case we don't have any. + * + * @return + * An object with at least title and content members. + */ +function no_context_content_type_render($subtype, $conf, $args, $context) { + $block = new stdClass(); + + $ctools_help = theme('advanced_help_topic', 'ctools', 'plugins', 'title'); + $ctools_plugin_example_help = theme('advanced_help_topic', 'ctools_plugin_example', 'Chaos-Tools--CTools--Plugin-Examples', 'title'); + + // The title actually used in rendering + $block->title = check_plain("No-context content type"); + $block->content = t(" + <div>Welcome to the CTools Plugin Example demonstration content type. + + This block is a content type which requires no context at all. It's like a custom block, + but not even that sophisticated. + + For more information on the example plugins, please see the advanced help for + + {$ctools_help} and {$ctools_plugin_example_help} + </div> + "); + if (!empty($conf)) { + $block->content .= '<div>The only information that can be displayed in this block comes from the code and its settings form: </div>'; + $block->content .= '<div style="border: 1px solid red;">' . var_export($conf, TRUE) . '</div>'; + } + + return $block; + +} + +/** + * 'Edit form' callback for the content type. + * This example just returns a form; validation and submission are standard drupal + * Note that if we had not provided an entry for this in hook_content_types, + * this could have had the default name + * ctools_plugin_example_no_context_content_type_edit_form. + * + */ +function no_context_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + $form['item1'] = array( + '#type' => 'textfield', + '#title' => t('Item1'), + '#size' => 50, + '#description' => t('The setting for item 1.'), + '#default_value' => !empty($conf['item1']) ? $conf['item1'] : '', + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + $form['item2'] = array( + '#type' => 'textfield', + '#title' => t('Item2'), + '#size' => 50, + '#description' => t('The setting for item 2'), + '#default_value' => !empty($conf['item2']) ? $conf['item2'] : '', + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + return $form; +} + +function no_context_content_type_edit_form_submit(&$form, &$form_state) { + foreach (array('item1', 'item2') as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/relcontext_content_type.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/relcontext_content_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..b0742e0c3a565fbc8c50855c15855e8caf652279 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/relcontext_content_type.inc @@ -0,0 +1,103 @@ +<?php + + +/** + * @file + * Content type that displays the relcontext context type. + * + * This example is for use with the relcontext relationship to show + * how we can get a relationship-context into a data type. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + // Used in add content dialogs. + 'title' => t('CTools example relcontext content type'), + 'admin info' => 'ctools_plugin_example_relcontext_content_type_admin_info', + 'content_types' => 'relcontext_content_type', + 'single' => TRUE, + 'render callback' => 'relcontext_content_type_render', + // Icon goes in the directory with the content type. Here, in plugins/content_types. + 'icon' => 'icon_example.png', + 'description' => t('Relcontext content type - works with relcontext context.'), + 'required context' => new ctools_context_required(t('Relcontext'), 'relcontext'), + 'category' => array(t('CTools Examples'), -9), + 'edit form' => 'relcontext_edit_form', + + // this example does not provide 'admin info', which would populate the + // panels builder page preview. + +); + +/** + * Run-time rendering of the body of the blcok + * + * @param $subtype + * @param $conf + * Configuration as done at admin time + * @param $args + * @param $context + * Context - in this case we don't have any + * + * @return + * An object with at least title and content members + */ +function relcontext_content_type_render($subtype, $conf, $args, $context) { + $data = $context->data; + $block = new stdClass(); + + // Don't forget to check this data if it's untrusted. + // The title actually used in rendering. + $block->title = "Relcontext content type"; + $block->content = t(" + This is a block of data created by the Relcontent content type. + Data in the block may be assembled from static text (like this) or from the + content type settings form (\$conf) for the content type, or from the context + that is passed in. <br /> + In our case, the configuration form (\$conf) has just one field, 'config_item_1; + and it's configured with: + "); + if (!empty($conf)) { + $block->content .= '<div style="border: 1px solid red;">' . var_export($conf['config_item_1'], TRUE) . '</div>'; + } + if (!empty($context)) { + $block->content .= '<br />The args ($args) were <div style="border: 1px solid yellow;" >' . + var_export($args, TRUE) . '</div>'; + } + $block->content .= '<br />And the relcontext context ($context->data->description) + (which was created from a + simplecontext context) was <div style="border: 1px solid green;" >' . + print_r($context->data->description, TRUE) . '</div>'; + return $block; +} + +/** + * 'Edit' callback for the content type. + * This example just returns a form. + * + */ +function relcontext_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['config_item_1'] = array( + '#type' => 'textfield', + '#title' => t('Config Item 1 (relcontext)'), + '#size' => 50, + '#description' => t('Setting for relcontext.'), + '#default_value' => !empty($conf['config_item_1']) ? $conf['config_item_1'] : '', + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + return $form; +} + +function relcontext_edit_form_submit(&$form, &$form_state) { + foreach (element_children($form) as $key) { + if (!empty($form_state['values'][$key])) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..82291d063fdc287045c28be7faff49cc9879ca6b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc @@ -0,0 +1,129 @@ +<?php + + +/** + * @file + * Sample ctools content type that takes advantage of context. + * + * This example uses the context it gets (simplecontext) to demo how a + * ctools content type can access and use context. Note that the simplecontext + * can be either configured manually into a panel or it can be retrieved via + * an argument. + * + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Simplecontext content type'), + 'content_types' => 'simplecontext_content_type', + // 'single' means not to be subtyped. + 'single' => TRUE, + // Name of a function which will render the block. + 'render callback' => 'simplecontext_content_type_render', + + // Icon goes in the directory with the content type. + 'icon' => 'icon_example.png', + 'description' => t('Simplecontext content type - works with a simplecontext context.'), + 'required context' => new ctools_context_required(t('Simplecontext'), 'simplecontext'), + 'edit form' => 'simplecontext_content_type_edit_form', + 'admin title' => 'ctools_plugin_example_simplecontext_content_type_admin_title', + + // presents a block which is used in the preview of the data. + // Pn Panels this is the preview pane shown on the panels building page. + 'admin info' => 'ctools_plugin_example_simplecontext_content_type_admin_info', + 'category' => array(t('CTools Examples'), -9), +); + +function ctools_plugin_example_simplecontext_content_type_admin_title($subtype, $conf, $context = NULL) { + $output = t('Simplecontext'); + if ($conf['override_title'] && !empty($conf['override_title_text'])) { + $output = filter_xss_admin($conf['override_title_text']); + } + return $output; +} + +/** + * Callback to provide administrative info (the preview in panels when building + * a panel). + * + * In this case we'll render the content with a dummy argument and + * a dummy context. + */ +function ctools_plugin_example_simplecontext_content_type_admin_info($subtype, $conf, $context = NULL) { + $context = new stdClass(); + $context->data = new stdClass(); + $context->data->description = t("no real context"); + $block = simplecontext_content_type_render($subtype, $conf, array("Example"), $context); + return $block; +} + +/** + * Run-time rendering of the body of the block (content type) + * + * @param $subtype + * @param $conf + * Configuration as done at admin time + * @param $args + * @param $context + * Context - in this case we don't have any + * + * @return + * An object with at least title and content members + */ +function simplecontext_content_type_render($subtype, $conf, $args, $context) { + $data = $context->data; + $block = new stdClass(); + + // Don't forget to check this data if it's untrusted. + // The title actually used in rendering. + $block->title = "Simplecontext content type"; + $block->content = t(" + This is a block of data created by the Simplecontext content type. + Data in the block may be assembled from static text (like this) or from the + content type settings form (\$conf) for the content type, or from the context + that is passed in. <br /> + In our case, the configuration form (\$conf) has just one field, 'config_item_1; + and it's configured with: + "); + if (!empty($conf)) { + $block->content .= '<div style="border: 1px solid red;">' . print_r(filter_xss_admin($conf['config_item_1']), TRUE) . '</div>'; + } + if (!empty($context)) { + $block->content .= '<br />The args ($args) were <div style="border: 1px solid yellow;" >' . + var_export($args, TRUE) . '</div>'; + } + $block->content .= '<br />And the simplecontext context ($context->data->description) was <div style="border: 1px solid green;" >' . + print_r($context->data->description, TRUE) . '</div>'; + return $block; +} + +/** + * 'Edit' callback for the content type. + * This example just returns a form. + * + */ +function simplecontext_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + $form['config_item_1'] = array( + '#type' => 'textfield', + '#title' => t('Config Item 1 for simplecontext content type'), + '#size' => 50, + '#description' => t('The stuff for item 1.'), + '#default_value' => !empty($conf['config_item_1']) ? $conf['config_item_1'] : '', + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + + return $form; +} + +function simplecontext_content_type_edit_form_submit(&$form, &$form_state) { + foreach (element_children($form) as $key) { + if (!empty($form_state['values'][$key])) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/contexts/relcontext.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/contexts/relcontext.inc new file mode 100644 index 0000000000000000000000000000000000000000..0c7ef113556a150a45208c71a150b4df575ace64 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/contexts/relcontext.inc @@ -0,0 +1,83 @@ +<?php + +/** + * @file + * Sample ctools context type plugin that + * is used in this demo to create a relcontext from an existing simplecontext. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Relcontext"), + 'description' => t('A relcontext object.'), + // Function to create the relcontext. + 'context' => 'ctools_plugin_example_context_create_relcontext', + // Function that does the settings. + 'settings form' => 'relcontext_settings_form', + 'keyword' => 'relcontext', + 'context name' => 'relcontext', +); + +/** + * Create a context, either from manual configuration (form) or from an argument on the URL. + * + * @param $empty + * If true, just return an empty context. + * @param $data + * If from settings form, an array as from a form. If from argument, a string. + * @param $conf + * TRUE if the $data is coming from admin configuration, FALSE if it's from a URL arg. + * + * @return + * a Context object. + */ +function ctools_plugin_example_context_create_relcontext($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('relcontext'); + $context->plugin = 'relcontext'; + if ($empty) { + return $context; + } + if ($conf) { + if (!empty($data)) { + $context->data = new stdClass(); + // For this simple item we'll just create our data by stripping non-alpha and + // adding 'sample_relcontext_setting' to it. + $context->data->description = 'relcontext_from__' . preg_replace('/[^a-z]/i', '', $data['sample_relcontext_setting']); + $context->data->description .= '_from_configuration_sample_simplecontext_setting'; + $context->title = t("Relcontext context from simplecontext"); + return $context; + } + } + else { + // $data is coming from an arg - it's just a string. + // This is used for keyword. + $context->title = "relcontext_" . $data->data->description; + $context->argument = $data->argument; + // Make up a bogus context. + $context->data = new stdClass(); + // For this simple item we'll just create our data by stripping non-alpha and + // prepend 'relcontext_' and adding '_created_from_from_simplecontext' to it. + $context->data->description = 'relcontext_' . preg_replace('/[^a-z]/i', '', $data->data->description); + $context->data->description .= '_created_from_simplecontext'; + return $context; + } +} + +function relcontext_settings_form($conf, $external = FALSE) { + $form = array(); + + $form['sample_relcontext_setting'] = array( + '#type' => 'textfield', + '#title' => t('Relcontext setting'), + '#size' => 50, + '#description' => t('Just an example setting.'), + '#default_value' => !empty($conf['sample_relcontext_setting']) ? $conf['sample_relcontext_setting'] : '', + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + return $form; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/contexts/simplecontext.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/contexts/simplecontext.inc new file mode 100644 index 0000000000000000000000000000000000000000..e19a84229617740ce8a4dd422aa4f0b4787799c8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/contexts/simplecontext.inc @@ -0,0 +1,134 @@ +<?php + + +/** + * @file + * Sample ctools context type plugin that shows how to create a context from an arg. + * + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Simplecontext"), + 'description' => t('A single "simplecontext" context, or data element.'), + 'context' => 'ctools_plugin_example_context_create_simplecontext', // func to create context + 'context name' => 'simplecontext', + 'settings form' => 'simplecontext_settings_form', + 'keyword' => 'simplecontext', + + // Provides a list of items which are exposed as keywords. + 'convert list' => 'simplecontext_convert_list', + // Convert keywords into data. + 'convert' => 'simplecontext_convert', + + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter some data to represent this "simplecontext".'), + ), +); + +/** + * Create a context, either from manual configuration or from an argument on the URL. + * + * @param $empty + * If true, just return an empty context. + * @param $data + * If from settings form, an array as from a form. If from argument, a string. + * @param $conf + * TRUE if the $data is coming from admin configuration, FALSE if it's from a URL arg. + * + * @return + * a Context object/ + */ +function ctools_plugin_example_context_create_simplecontext($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('simplecontext'); + $context->plugin = 'simplecontext'; + + if ($empty) { + return $context; + } + + if ($conf) { + if (!empty($data)) { + $context->data = new stdClass(); + // For this simple item we'll just create our data by stripping non-alpha and + // adding '_from_configuration_item_1' to it. + $context->data->item1 = t("Item1"); + $context->data->item2 = t("Item2"); + $context->data->description = preg_replace('/[^a-z]/i', '', $data['sample_simplecontext_setting']); + $context->data->description .= '_from_configuration_sample_simplecontext_setting'; + $context->title = t("Simplecontext context from config"); + return $context; + } + } + else { + // $data is coming from an arg - it's just a string. + // This is used for keyword. + $context->title = $data; + $context->argument = $data; + // Make up a bogus context + $context->data = new stdClass(); + $context->data->item1 = t("Item1"); + $context->data->item2 = t("Item2"); + + // For this simple item we'll just create our data by stripping non-alpha and + // adding '_from_simplecontext_argument' to it. + $context->data->description = preg_replace('/[^a-z]/i', '', $data); + $context->data->description .= '_from_simplecontext_argument'; + $context->arg_length = strlen($context->argument); + return $context; + } +} + +function simplecontext_settings_form($conf, $external = FALSE) { + if (empty($conf)) { + $conf = array( + 'sample_simplecontext_setting' => 'default simplecontext setting', + ); + } + $form = array(); + $form['sample_simplecontext_setting'] = array( + '#type' => 'textfield', + '#title' => t('Setting for simplecontext'), + '#size' => 50, + '#description' => t('An example setting that could be used to configure a context'), + '#default_value' => $conf['sample_simplecontext_setting'], + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + return $form; +} + + + +/** + * Provide a list of sub-keywords. + * + * This is used to provide keywords from the context for use in a content type, + * pane, etc. + */ +function simplecontext_convert_list() { + return array( + 'item1' => t('Item1'), + 'item2' => t('Item2'), + 'description' => t('Description'), + ); +} + +/** + * Convert a context into a string to be used as a keyword by content types, etc. + */ +function simplecontext_convert($context, $type) { + switch ($type) { + case 'item1': + return $context->data->item1; + case 'item2': + return $context->data->item2; + case 'description': + return $context->data->description; + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/panels.pages.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/panels.pages.inc new file mode 100644 index 0000000000000000000000000000000000000000..ee61e0a9a7ddc6678aa024933e1f22b1f05ef41b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/panels.pages.inc @@ -0,0 +1,214 @@ +<?php + +/** + * @file + * Holds the panels pages export. + */ + +/** + * Implementation of hook_default_panel_pages() + */ +function ctools_plugin_example_default_panel_pages() { + $page = new stdClass(); + $page->pid = 'new'; + $page->did = 'new'; + $page->name = 'ctools_plugin_example_demo_panel'; + $page->title = 'Panels Plugin Example Demo Panel'; + $page->access = array(); + $page->path = 'demo_panel'; + $page->load_flags = 1; + $page->css_id = ''; + $page->arguments = array( + 0 => + array( + 'name' => 'simplecontext_arg', + 'id' => 1, + 'default' => '404', + 'title' => '', + 'identifier' => 'Simplecontext arg', + 'keyword' => 'simplecontext', + ), + ); + $page->relationships = array( + 0 => + array( + 'context' => 'argument_simplecontext_arg_1', + 'name' => 'relcontext_from_simplecontext', + 'id' => 1, + 'identifier' => 'Relcontext from Simplecontext', + 'keyword' => 'relcontext', + ), + ); + $page->no_blocks = '0'; + $page->switcher_options = array(); + $page->menu = '0'; + $page->contexts = array(); + $display = new ctools_display(); + $display->did = 'new'; + $display->layout = 'threecol_33_34_33_stacked'; + $display->layout_settings = array(); + $display->panel_settings = array(); + $display->content = array(); + $display->panels = array(); + $pane = new stdClass(); + $pane->pid = 'new-1'; + $pane->panel = 'left'; + $pane->type = 'custom'; + $pane->shown = '1'; + $pane->subtype = 'custom'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'title' => '"No Context Item"', + 'body' => 'The "no context item" content type is here to demonstrate that you can create a content_type that does not require a context. This is probably the same as just creating a custom php block on the fly, and might serve the same purpose.', + 'format' => '1', + ); + $pane->cache = array(); + $display->content['new-1'] = $pane; + $display->panels['left'][0] = 'new-1'; + $pane = new stdClass(); + $pane->pid = 'new-2'; + $pane->panel = 'left'; + $pane->type = 'no_context_item'; + $pane->shown = '1'; + $pane->subtype = 'description'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'item1' => 'one', + 'item2' => 'two', + 'item3' => 'three', + ); + $pane->cache = array(); + $display->content['new-2'] = $pane; + $display->panels['left'][1] = 'new-2'; + $pane = new stdClass(); + $pane->pid = 'new-3'; + $pane->panel = 'middle'; + $pane->type = 'custom'; + $pane->shown = '1'; + $pane->subtype = 'custom'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'title' => 'Simplecontext', + 'body' => 'The "Simplecontext" content and content type demonstrate a very basic context and how to display it. + + Simplecontext includes configuration, so it can get info from the config. It can also get its information to run from a simplecontext context, generated either from an arg to the panels page or via explicitly adding a context to the page.', + 'format' => '1', + ); + $pane->cache = array(); + $display->content['new-3'] = $pane; + $display->panels['middle'][0] = 'new-3'; + $pane = new stdClass(); + $pane->pid = 'new-4'; + $pane->panel = 'middle'; + $pane->type = 'simplecontext_item'; + $pane->shown = '1'; + $pane->subtype = 'description'; + $pane->access = array( + 0 => '2', + 1 => '4', + ); + $pane->configuration = array( + 'context' => 'argument_simplecontext_arg_1', + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'config_item_1' => 'simplecontext called from arg', + ); + $pane->cache = array(); + $display->content['new-4'] = $pane; + $display->panels['middle'][1] = 'new-4'; + $pane = new stdClass(); + $pane->pid = 'new-5'; + $pane->panel = 'right'; + $pane->type = 'custom'; + $pane->shown = '1'; + $pane->subtype = 'custom'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'title' => 'Relcontext', + 'body' => 'The relcontext content_type gets its data from a relcontext, which is an example of a relationship. This panel should be run with an argument like "/xxx", which allows the simplecontext to get its context, and then the relcontext is configured in this panel to get (create) its data from the simplecontext.', + 'format' => '1', + ); + $pane->cache = array(); + $display->content['new-5'] = $pane; + $display->panels['right'][0] = 'new-5'; + $pane = new stdClass(); + $pane->pid = 'new-6'; + $pane->panel = 'right'; + $pane->type = 'relcontext_item'; + $pane->shown = '1'; + $pane->subtype = 'description'; + $pane->access = array(); + $pane->configuration = array( + 'context' => 'relationship_relcontext_from_simplecontext_1', + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'config_item_1' => 'default1', + ); + $pane->cache = array(); + $display->content['new-6'] = $pane; + $display->panels['right'][1] = 'new-6'; + $pane = new stdClass(); + $pane->pid = 'new-7'; + $pane->panel = 'top'; + $pane->type = 'custom_php'; + $pane->shown = '1'; + $pane->subtype = 'custom_php'; + $pane->access = array(); + $pane->configuration = array( + 'style' => 'default', + 'override_title' => 0, + 'override_title_text' => '', + 'css_id' => '', + 'css_class' => '', + 'title' => '', + 'body' => '$arg = arg(1); + $arg0 = arg(0); + if (!$arg) { + $block->content = <<<END + <em>This page is intended to run with an arg and you don\'t have one.</em> + <br /> + Without an arg, the page doesn\'t have any context. + <br />Please try something like "/$arg0/xxx" +END; + + $block->title = "This is intended to run with an argument"; + } else { + $block->content = "The arg for this page is \'$arg\'"; + }', + ); + $pane->cache = array(); + $display->content['new-7'] = $pane; + $display->panels['top'][0] = 'new-7'; + $page->display = $display; + $page->displays = array(); + $pages['ctools_plugin_example'] = $page; + + + return $pages; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc new file mode 100644 index 0000000000000000000000000000000000000000..6224621042338ee1c60bc760c4d4eaa4068c4a19 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc @@ -0,0 +1,50 @@ +<?php + + +/** + * @file + * + * Sample relationship plugin. + * + * We take a simplecontext, look in it for what we need to make a relcontext, and make it. + * In the real world, this might be getting a taxonomy id from a node, for example. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Relcontext from simplecontext"), + 'keyword' => 'relcontext', + 'description' => t('Adds a relcontext from existing simplecontext.'), + 'required context' => new ctools_context_required(t('Simplecontext'), 'simplecontext'), + 'context' => 'ctools_relcontext_from_simplecontext_context', + 'settings form' => 'ctools_relcontext_from_simplecontext_settings_form', +); + +/** + * Return a new context based on an existing context. + */ +function ctools_relcontext_from_simplecontext_context($context = NULL, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data)) { + return ctools_context_create_empty('relcontext', NULL); + } + + // You should do error-checking here. + + // Create the new context from some element of the parent context. + // In this case, we'll pass in the whole context so it can be used to + // create the relcontext. + return ctools_context_create('relcontext', $context); +} + +/** + * Settings form for the relationship. + */ +function ctools_relcontext_from_simplecontext_settings_form($conf) { + // We won't configure it in this case. + return array(); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/about.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/about.html new file mode 100644 index 0000000000000000000000000000000000000000..39493ffe7e8a9ecef50872bdfd3899201c28aa0b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/about.html @@ -0,0 +1,30 @@ +The Chaos Tool Suite is a series of tools for developers to make code that I've found to be very useful to Views and Panels more readily available. Certain methods of doing things, particularly with AJAX, exportable objects, and a plugin system are proving to be ideas that are useful outside of just Views and Panels. This module does not offer much directly ot the end user, but instead creates a library for other modules to use. If you are an end user and some module asked you to install the CTools suite, then this is far as you really need to go. If you're a developer and are interested in these tools, read on! + +<h3>Tools provided by CTools</h3> +<dl> +<dt><a href="&topic:ctools/plugins&">Plugins</a></dt> +<dd>The plugins tool allows a module to allow <b>other</b> modules (and themes!) to provide plugins which provide some kind of functionality or some kind of task. For example, in Panels there are several types of plugins: Content types (which are like blocks), layouts (which are page layouts) and styles (which can be used to style a panel). Each plugin is represented by a .inc file, and the functionaly they offer can differ wildly. + +<dt><a href="&topic:ctools/context&">Context</a></dt> +<dd>Context is the idea that the objects that are used in page generation have more value than simply creating a single piece of output. Instead, contexts can be used to create multiple pieces of content that can all be put onto the page. Additionally, contexts can be used to derive other contexts via relationships, such as determining the node author and displaying data about the new context.</dd> + +<dt><a href="&topic:ctools/ajax&">AJAX Tools</a></dt> +<dd>AJAX (also known as AHAH) is a method of allowing the browser and the server to communicate without requiring a page refresh. It can be used to create complicated interactive forms, but it is somewhat difficult to integrate into Drupal's Form API. These tools make it easier to accomplish this goal. In addition, CTools provides a few other javascript helpers, such as a modal dialog, a collapsible div, a simple dropdown and dependent checkboxes. + +<dt><a href="&topic:ctools/css&">CSS scrubbing and caching</a></dt> +<dd>Drupal comes with a fantastic array of tools to ensure HTML is safe to output, but does not contain any similar tools for CSS. CTools provides a small tool to sanitize CSS so that user-input CSS code can still be safely used. It also provides a method for caching CSS for better performance.</dd> + +<dt><a href="&topic:ctools/export&">Exportable objects</a></dt> +<dd>Views and Panels both use objects that can either be in code or in the database, and the object can be exported into a piece of PHP code so that it can be moved from site to site or out of the database entirely. This library abstracts that so that other modules can use this same concept for their data.</dd> + +<dt><a href="&topic:ctools/form&">Form tools</a></dt> +<dd>Drupal 6's FAPI really improved over Drupal 5, and made a lot of things possible. Still, it missed a few items that were needed to make form wizards and truly dynamic AJAX forms possible. CTools includes a replacement for drupal_get_form() that has a few more options and allows the caller to examine the $form_state once the form has completed.</dd> + +<dt><a href="&topic:ctools/wizard&">Form wizards</a></dt> +<dd>Finally! An easy way to have form wizards, which is any 'form' which is actually a string of forms that build up to a final conclusion. The form wizard supports a single entry point, the ability to choose whether or not the user can go forward/back/up on the form and easy callbacks to handle the difficult job of dealing with data in between forms.</dd> + +<dt><a href="&topic:ctools/object-cache&">Temporary object cache</a></dt> +<dd>For normal forms, all of the data needed for an object is stored in the form so that the browser handles a lot of the work. For multi-step and ajax forms, however, this is impractical, and letting the browser store data can be insecure. The object cache provides a non-volatile location to store temporary data while the form is being worked on. This is much safer than the standard Drupal caching mechanism, which is volatile, meaning it can be cleared at any time and any system using it must be capable of recreating the data that was there. This system also allows for object locking, since any object which has an item in the cache from another person can be assumed to be 'locked for editing'.</dd> + + +</dl> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/ajax.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/ajax.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/context-access.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-access.html new file mode 100644 index 0000000000000000000000000000000000000000..ef2ddbf849ee0a53c3b090d516a99404454a1ccf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-access.html @@ -0,0 +1,14 @@ + +access plugins allow context based access control to pages. + + + 'title' => Title of the plugin + 'description' => Description of the plugin + 'callback' => callback to see if there is access is available. params: $conf, $contexts, $account + 'required context' => zero or more required contexts for this access plugin + 'default' => an array of defaults or a callback giving defaults + 'settings form' => settings form. params: &$form, &$form_state, $conf + settings form validate + settings form submit + +warning: Your settings array will be stored IN THE MENU SYSTEM to reduce loads, so be TRIM. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/context-arguments.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-arguments.html new file mode 100644 index 0000000000000000000000000000000000000000..f19f597c5528933f802ddd658c7d45b7b928b22b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-arguments.html @@ -0,0 +1,19 @@ + +Arguments create a context from external input, which is assumed to be a +string as though it came from a URL element. + + 'title' => title + 'description' => Description + 'keyword' => Default keyword for the context + 'context' => Callback to create the context. Params: $arg = NULL, $conf = NULL, $empty = FALSE + + 'default' => either an array of default settings or a string which is a callback or null to not use. + + 'settings form' => params: $form, $form_state, $conf -- gets the whole form. Should put anything it wants to keep automatically in $form['settings'] + 'settings form validate' => params: $form, $form_state + 'settings form submit' => params: $form, $form_state + + 'criteria form' => params: $form, &$form_state, $conf, $argument, $id -- gets the whole argument. It should only put form widgets in $form[$id]. $conf may not be properly initialized so always guard against this due to arguments being changed and handlers not being updated to match. + + submit + validate + + 'criteria select' => returns true if the selected criteria matches the context. params: $context, $conf diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/context-content.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-content.html new file mode 100644 index 0000000000000000000000000000000000000000..7c18d519a09c64a644b3c080cd098d48799469ab --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-content.html @@ -0,0 +1,246 @@ +<p>The CTools pluggable content system provides various pieces of +content as discrete bits of data that can be added to other +applications, such as Panels or Dashboard via the UI. Whatever the +content is added to stores the configuration for that individual piece +of content, and provides this to the content.</p> + +<p>Each content type plugin will be contained in a .inc file, with +subsidiary files, if necessary, in or near the same directory. Each +content type consists of some information and one or more subtypes, +which all use the same renderer. Subtypes are considered to be +instances of the type. For example, the 'views' content type would have +each view in the system as a subtype. Many content types will have +exactly one subtype.</p> + +<p>Because the content and forms can be provided via ajax, the plugin +also provides a list of CSS and JavaScript information that should be available +on whatever page the content or forms may be AJAXed onto.</p> + +<p>For the purposes of selecting content from the UI, each content +subtype will have the following information:</p> + +<ul> + <li>A title</li> + + <li>A short description</li> + + <li>A category [Do we want to add hierarchy categories? Do we want + category to be more than just a string?]</li> + + <li>An icon [do we want multiple icons? This becomes a hefty + requirement]</li> +</ul> + +<p>Each piece of content provides one or more configuration forms, if +necessary, and the system that includes the content will handle the +data storage. These forms can be provided in sequence as wizards or as +extra forms that can be accessed through advanced administration.</p> + +<p>The plugin for a content type should contain:</p> + +<dl> + <dt>title</dt> + + <dd>For use on the content permissions screen.</dd> + + <dt>content types</dt> + + <dd>Either an array of content type definitions, or a callback that + will return content type definitions. This callback will get the + plugin definition as an argument.</dd> + + <dt>content type</dt> + + <dd>[Optional] Provide a single content type definition. This is only + necessary if content types might be intensive.</dd> + + <dt>render callback</dt> + + <dd> + The callback to render the content. Parameters: + + <dl> + <dt>$subtype</dt> + + <dd>The name of the subtype being rendered. NOT the loaded + subtype data.</dd> + + <dt>$conf</dt> + + <dd>The stored configuration for the content.</dd> + + <dt>$args</dt> + + <dd>Any arguments passed.</dd> + + <dt>$context</dt> + + <dd>An array of contexts requested by the required contexts and + assigned by the configuration step.</dd> + + <dt>$incoming_content</dt> + + <dd>Any 'incoming content' if this is a wrapper.</dd> + </dl> + </dd> + + <dt>admin title</dt> + + <dd>A callback to provide the administrative title. If it is not a + function, then it will be counted as a string to use as the admin + title.</dd> + + <dt>admin info</dt> + + <dd>A callback to provide administrative information about the + content, to be displayed when manipulating the content. It should + contain a summary of configuration.</dd> + + <dt>edit form</dt> + + <dd> + Either a single form ID or an array of forms *keyed* by form ID + with the value to be used as the title of the form. %title me be + used as a placeholder for the administrative title if necessary. + Example: + <pre> + array( + 'ctools_example_content_form_second' => t('Configure first form'), + 'ctools_example_content_form_first' => t('Configure second form'), + ), +</pre>The first form will always have required configuration added to +it. These forms are normal FAPI forms, but you do not need to provide +buttons, these will be added by the form wizard. + </dd> + + <dt>add form</dt> + + <dd>[Optional] If different from the edit forms, provide them here in + the same manner. Also may be set to FALSE to not have an add + form.</dd> + + <dt>css</dt> + + <dd>A file or array of CSS files that are necessary for the + content.</dd> + + <dt>js</dt> + + <dd>A file or array of javascript files that are necessary for the + content to be displayed.</dd> + + <dt>admin css</dt> + + <dd>A file or array of CSS files that are necessary for the + forms.</dd> + + <dt>admin js</dt> + + <dd>A file or array of JavaScript files that are necessary for the + forms.</dd> + + <dt>extra forms</dt> + + <dd>An array of form information to handle extra administrative + forms.</dd> + + <dt>no title override</dt> + + <dd>Set to TRUE if the title cannot be overridden.</dd> + + <dt>single</dt> + + <dd>Set to TRUE if this content provides exactly one subtype.</dd> + + <dt>render last</dt> + + <dd>Set to true if for some reason this content needs to render after + other content. This is primarily used for forms to ensure that render + order is correct.</dd> +</dl> + +<p>TODO: many of the above callbacks can be assumed based upon +patterns: modulename + '_' + name + '_' + function. i.e, render, +admin_title, admin_info, etc.</p> + +<p>TODO: Some kind of simple access control to easily filter out +content.</p> + +<p>The subtype definition should contain:</p> + +<dl> + <dt>title</dt> + + <dd>The title of the subtype.</dd> + + <dt>icon</dt> + + <dd>The icon to display for the subtype.</dd> + + <dt>path</dt> + + <dd>The path for the icon if it is not in the same directory as the + plugin.</dd> + + <dt>description</dt> + + <dd>The short description of the subtype, to be used when selecting + it in the UI.</dd> + + <dt>category</dt> + + <dd>Either a text string for the category, or an array of the text + string followed by the category weight.</dd> + + <dt>required context [Optional]</dt> + + <dd>Either a ctools_context_required or ctools_context_optional or + array of contexts for this content. If omitted, no contexts are + used.</dd> +</dl> + +<h3>Rendered content</h3> + +<p>Rendered content is a little more than just HTML.</p> + +<dl> + <dt>title</dt> + + <dd>The safe to render title of the content.</dd> + + <dt>content</dt> + + <dd>The safe to render HTML content.</dd> + + <dt>links</dt> + + <dd>An array of links associated with the content suitable for + theme('links').</dd> + + <dt>more</dt> + + <dd>An optional 'more' link (destination only)</dd> + + <dt>admin_links</dt> + + <dd>Administrative links associated with the content, suitable for + theme('links').</dd> + + <dt>feeds</dt> + + <dd>An array of feed icons or links associated with the content. Each + member of the array is rendered HTML.</dd> + + <dt>type</dt> + + <dd>The content type.</dd> + + <dt>subtype</dt> + + <dd>The content subtype. These two may be used together as + module-delta for block style rendering.</dd> +</dl> + +<h3>Todo: example</h3> + +<p>Todo after implementations are updated to new version.</p> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/context-context.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-context.html new file mode 100644 index 0000000000000000000000000000000000000000..23a9631540e7847ea7748df0f880b0b4eca6a403 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-context.html @@ -0,0 +1,12 @@ + +Context plugin data: + + 'title' => Visible title + 'description' => Description of context + 'context' => Callback to create a context. Params: $empty, $data = NULL, $conf = FALSE + 'settings form' => Callback to show a context setting form. Params: ($conf, $external = FALSE) + 'settings form validate' => params: ($form, &$form_values, &$form_state) + 'settings form submit' => params: 'ctools_context_node_settings_form_submit', + 'keyword' => The default keyword to use. + 'context name' => The unique identifier for this context for use by required context checks. + 'no ui' => if TRUE this context cannot be selected. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/context-relationships.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-relationships.html new file mode 100644 index 0000000000000000000000000000000000000000..547f89129515e1a8c567c3605fc648a1d49974b4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/context-relationships.html @@ -0,0 +1,10 @@ + + 'title' => The title to display. + 'description' => Description to display. + 'keyword' => Default keyword for the context created by this relationship. + 'required context' => One or more ctools_context_required/optional objects + describing the context input. + new panels_required_context(t('Node'), 'node'), + 'context' => The callback to create the context. Params: ($context = NULL, $conf) + 'settings form' => Settings form. Params: $conf + 'settings form validate' => Validate. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/context.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/context.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/ctools.help.ini b/drupal/sites/default/boinc/modules/contrib/ctools/help/ctools.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..a3f2075d0e82a1ba840e9c00466bbbba2654f7c7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/ctools.help.ini @@ -0,0 +1,93 @@ +[advanced help settings] +line break = TRUE + +[about] +title = About Chaos Tool Suite +weight = -100 + +[context] +title = Context tool +weight = -40 + +[context-access] +title = Context based access control plugins +parent = context + +[context-context] +title = Context plugins +parent = context + +[context-arguments] +title = Argument plugins +parent = context + +[context-relationships] +title = Relationship plugins +parent = context + +[context-content] +title = Content plugins +parent = context + +[css] +title = CSS scrubbing and caching tool + +[menu] +title = Miscellaneous menu helper tool + +[plugins] +title = Plugins and APIs tool +weight = -50 + +[plugins-api] +title = Implementing APIs +parent = plugins + +[plugins-creating] +title = Creating plugins +parent = plugins + +[plugins-implementing] +title = Implementing plugins +parent = plugins + +[export] +title = Exportable objects tool + +[export-ui] +title = Exportable objects UI creator + +[form] +title = Form tools + +[wizard] +title = Form wizard tool + +[ajax] +title = AJAX and Javascript helper tools +weight = -30 + +[modal] +title = Javascript modal tool +parent = ajax + +[collapsible-div] +title = Javascript collapsible DIV +parent = ajax + +[dropdown] +title = Javascript dropdown +parent = ajax + +[dependent] +title = Dependent checkboxes and radio buttons +parent = ajax + +[object-cache] +title = Temporary object caching + +; A bunch of this stuff we'll put in panels. + +[plugins-content] +title = Creating content type plugins +parent = panels%api diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/export-ui.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/export-ui.html new file mode 100644 index 0000000000000000000000000000000000000000..f836a1809797ac718afb50c0f47c21d782a88f24 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/export-ui.html @@ -0,0 +1,84 @@ +Most user interfaces for exportables are very similar, so CTools includes a tool to provide the framework for the most common UI. This tool is a plugin of the 'export_ui' type. In order to create a UI for your exportable object with this tool, you first need to ensure that your module supports the plugin: + +<pre> +function HOOK_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && $plugin == 'export_ui') { + return 'plugins/' . $plugin; + } +} +</pre> + +Then, you need to create a plugin .inc file describing your UI. Most of the UI runs with sane but simple defaults, so for the very simplest UI you don't need to do very much. This is a very simple example plugin for the 'example' export type: + +<pre> +$plugin = array( + // The name of the table as found in the schema in hook_install. This + // must be an exportable type with the 'export' section defined. + 'schema' => 'example', + + // The access permission to use. If not provided it will default to + // 'administer site configuration' + 'access' => 'administer example', + + // You can actually define large chunks of the menu system here. Nothing + // is required here. If you leave out the values, the prefix will default + // to admin/build and the item will default to the plugin name. + 'menu' => array( + 'menu prefix' => 'admin/build', + 'menu item' => 'example', + // Title of the top level menu. Note this should not be translated, + // as the menu system will translate it. + 'menu title' => 'Example', + // Description of the top level menu, which is usually needed for + // menu items in an administration list. Will be translated + // by the menu system. + 'menu description' => 'Administer site example objects.', + ), + + // These are required to provide proper strings for referring to the + // actual type of exportable. "proper" means it will appear at the + // beginning of a sentence. + 'title singular' => t('example'), + 'title singular proper' => t('Example'), + 'title plural' => t('examples'), + 'title plural proper' => t('Examples'), + + // This will provide you with a form for editing the properties on your + // exportable, with validate and submit handler. + // + // The item being edited will be in $form_state['item']. + // + // The submit handler is only responsible for moving data from + // $form_state['values'] to $form_state['item']. + // + // All callbacks will accept &$form and &$form_state as arguments. + 'form' => array( + 'settings' => 'example_ctools_export_ui_form', + 'validate' => 'example_ctools_export_ui_form_validate', + 'submit' => 'example_ctools_export_ui_form_submit', + ), + +); +</pre> + +For a more complete list of what you can set in your plugin, please see ctools_export_ui_defaults() in includes/export-ui.inc to see what the defaults are. + +<h3>More advanced UIs</h3> +The bulk of this UI is built on an class called ctools_export_ui, which is itself stored in ctools/plugins/export_ui as the default plugin. Many UIs will have more complex needs than the defaults provide. Using OO and overriding methods can allow an implementation to use the basics and still provide more where it is needed. To utilize this, first add a 'handler' directive to your plugin .inc file: + +<pre> + 'handler' => array( + 'class' => 'ctools_export_ui_example', + 'parent' => 'ctools_export_ui', + ), +</pre> + +Then create your class in ctools_export_ui_example.class.php in your plugins directory: + +<pre> +class ctools_export_ui_example extends ctools_export_ui { + +} +</pre> + +You can override any method found in the class (see the source file for details). In particular, there are several list methods that are good candidates for overriding if you need to provide richer data for listing, sorting or filtering. If you need multi-step add/edit forms, you can override edit_page(), add_page(), clone_page(), and import_page() to put your wizard in place of the basic editing system. For an example of how to use multi-step wizards, see the import_page() method. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/export.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/export.html new file mode 100644 index 0000000000000000000000000000000000000000..88fb9f2371b152428dbb948048a48c6f826277fc --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/export.html @@ -0,0 +1,234 @@ +Exportable objects are objects that can live either in the database or in code, or in both. If they live in both, then the object in code is considered to be "overridden", meaning that the version in code is ignored in favor of the version in the database. + +The main benefit to this is that you can move objects that are intended to be structure or feature-related into code, thus removing them entirely from the database. This is a very important part of the deployment path, since in an ideal world, the database is primarily user generated content, whereas site structure and site features should be in code. However, many many features in Drupal rely on objects being in the database and provide UIs to create them. + +Using this system, you can give your objects dual life. They can be created in the UI, exported into code and put in revision control. Views and Panels both use this system heavily. Plus, any object that properly implements this system can be utilized by the Features module to be used as part of a bundle of objects that can be turned into feature modules. + +Typically, exportable objects have two identifiers. One identifier is a simple serial used for database identification. It is a primary key in the database and can be used locally. It also has a name which is an easy way to uniquely identify it. This makes it much less likely that importing and exporting these objects across systems will have collisions. They still can, of course, but with good name selection, these problems can be worked around. + +<h3>Making your objects exportable</h3> +To make your objects exportable, you do have to do a medium amount of work. +<ol> +<li>Create a chunk of code in your object's schema definition in the .install file to introduce the object to CTools' export system.</li> +<li>Create a load function for your object that utilizes ctools_export_load_object().</li> +<li>Create a save function for your object that utilizes drupal_write_record() or any method you desire.</li> +<li>Create an import and export mechanism from the UI.</li> +</ol> +<h3>The export section of the schema file</h3> + +Exportable objects are created by adding definition to the schema in an 'export' section. For example: + +<pre> +function mymodule_schema() { + $schema['mymodule_myobj'] = array( + 'description' => t('Table storing myobj definitions.'), + 'export' => array( + 'key' => 'name', + 'key name' => 'Name', + 'primary key' => 'oid', + 'identifier' => 'myobj', // Exports will be as $myobj + 'default hook' => 'default_mymodule_myobj', // Function hook name. + 'api' => array( + 'owner' => 'mymodule', + 'api' => 'default_mymodule_myobjs', // Base name for api include files. + 'minimum_version' => 1, + 'current_version' => 1, + ), + // If the key is stored in a table that is joined in, specify it: + 'key in table' => 'my_join_table', + + ), + + // If your object's data is split up across multiple tables, you can + // specify additional tables to join. This is very useful when working + // with modules like exportables.module that has a special table for + // translating keys to local database IDs. + // + // The joined table must have its own schema definition. + // + // If using joins, you should implement a 'delete callback' (see below) + // to ensure that deletes happen properly. export.inc does not do this + // automatically! + 'join' => array( + 'exportables' => array( + // The following parameters will be used in this way: + // SELECT ... FROM {mymodule_myobj} t__0 INNER JOIN {my_join_table} t__1 ON t__0.id = t__1.id AND extras + 'table' => 'my_join_table', + 'left_key' => 'format', + 'right_key' => 'id', + // Optionally you can define extra clauses to add to the INNER JOIN + 'extras' => "AND extra_clauses", + + // You must specify which fields will be loaded. These fields must + // exist in the schema definition of the joined table. + 'load' => array( + 'machine', + ), + + // And finally you can define other tables to perform INNER JOINS + //'other_joins' => array( + // 'table' => ... + //), + ), + ) + 'fields' => array( + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this object. Used to identify it programmatically.', + ), + 'oid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'Primary ID field for the table. Not used for anything except internal lookups.', + 'no export' => TRUE, // Do not export database-only keys. + ), + // ...... + 'primary key' => array('oid'), + 'unique keys' => array( + 'name' => array('name'), + ), + ); + return $schema; +} +</pre> + +<dl> +<dt>key</dt> +<dd>This is the primary key of the exportable object and should be a string as names are more portable across systems. It is possible to use numbers here, but be aware that export collisions are very likely. Defaults to 'name'.</dd> + +<dt>key name</dt> +<dd>Human readable title of the export key. Defaults to 'Name'. Because the schema is cached, do not translate this. It must instead be translated when used.</dd> + +<dt>primary key</dt> +<dd>Objects should contain a primary key which is a database identifier primarily used to determine if an object has been written or not. This is required for the default CRUD save callback to work.</dd> + +<dt>object</dt> +<dd>The class the object should be created as, if 'object factory' is not set. If this is not set either, defaults as stdClass.</dd> + +<dt>object factory</dt> +<dd>Function used to create the object. The function receives the schema and the loaded data as a parameters: your_factory_function($schema, $data). If this is set, 'object' has no effect since you can use your function to create whatever class you wish.</dd> + +<dt>can disable</dt> +<dd>Control whether or not the exportable objects can be disabled. All this does is cause the 'disabled' field on the object to always be set appropriately, and a variable is kept to record the state. Changes made to this state must be handled by the owner of the object. Defaults to TRUE.</dd> + +<dt>status</dt> +<dd>Exportable objects can be enabled or disabled, and this status is stored in a variable. This defines what variable that is. Defaults to: 'default_' . $table.</dd> + +<dt>default hook</dt> +<dd>What hook to invoke to find exportable objects that are currently defined. These will all be gathered into a giant array. Defaults to 'default_' . $table.</dd> + +<dt>identifier</dt> +<dd>When exporting the object, the identifier is the variable that the exported object will be placed in. Defaults to $table.</dd> + +<dt>bulk export</dt> +<dd>Declares whether or not the exportable will be available for bulk exporting.</dd> + +<dt>export type string</dt> +<dd>The export type string (Local, Overridden, Database) is normally stored as $item->type. Since type is a very common keyword, it's possible to specify what key to actually use. </dd> + +<dt>list callback</dt> +<dd>Bulk export callback to provide a list of exportable objects to be chosen for bulk exporting. Defaults to $module . '_' . $table . '_list' if the function exists. If it is not, a default listing function will be provided that will make a best effort to list the titles. See ctools_export_default_list().</dd> + +<dt>to hook code callback</dt> +<dd>Function used to generate an export for the bulk export process. This is only necessary if the export is more complicated than simply listing the fields. Defaults to $module . '_' . $table . '_to_hook_code'.</dt> +</dl> + +<dt>create callback</dt> +<dd>CRUD callback to use to create a new exportable item in memory. If not provided, the default function will be used. The single argument is a boolean used to determine if defaults should be set on the object. This object will not be written to the database by this callback.</dd> + +<dt>load callback</dt> +<dd>CRUD callback to use to load a single item. If not provided, the default load function will be used. The callback will accept a single argument which should be an identifier of the export key.</dd> + +<dt>load all callback</dt> +<dd>CRUD callback to use to load all items, usually for administrative purposes. If not provided, the default load function will be used. The callback will accept a single argument to determine if the load cache should be reset or not.</dd> + +<dt>save callback</dt> +<dd>CRUD callback to use to save a single item. If not provided, the default save function will be used. The callback will accept a single argument which should be the complete exportable object to save.</dd> + +<dt>delete callback</dt> +<dd>CRUD callback to use to delete a single item. If not provided, the default delete function will be used. The callback will accept a single argument which can be *either* the object or just the export key to delete. The callback MUST be able to accept either.</dd> + +<dt>export callback</dt> +<dd>CRUD callback to use for exporting. If not provided, the default export function will be used. The callback will accept two arguments, the first is the item to export, the second is the indent to place on the export, if any.</dd> + +<dt>import callback</dt> +<dd>CRUD callback to use for importing. If not provided, the default export function will be used. This function will accept the code as a single argument and, if the code evaluates, return an object represented by that code. In the case of failure, this will return a string with human readable errors.</dd> + +In addition, each field can contain the following: +<dl> +<dt>no export</dt> +<dd>Set to TRUE to prevent that field from being exported.</dd> + +<dt>export callback</dt> +<dd>A function to override the export behavior. It will receive ($myobject, $field, $value, $indent) as arguments. By default, fields are exported through ctools_var_export().</dd> +</dl> + +<h3>Reserved keys on exportable objects</h3> + +Exportable objects have several reserved keys that are used by the CTools export API. Each key can be found at <code>$myobj->{$key}</code> on an object loaded through <code>ctools_export_load_object()</code>. Implementing modules should not use these keys as they will be overwritten by the CTools export API. +<dl> +<dt>api_version</dt> +<dd>The API version that this object implements.</dd> + +<dt>disabled</dt> +<dd>A boolean for whether the object is disabled.</dd> + +<dt>export_module</dt> +<dd>For objects that live in code, the module which provides the default object.</dd> + +<dt>export_type</dt> +<dd>A bitmask representation of an object current storage. You can use this bitmask in combination with the <code>EXPORT_IN_CODE</code> and <code>EXPORT_IN_DATABASE</code> constants to test for an object's storage in your code. +</dd> + +<dt>in_code_only</dt> +<dd>A boolean for whether the object lives only in code.</dd> + +<dt>table</dt> +<dd>The schema API table that this object belongs to.</dd> + +<dt>type</dt> +<dd>A string representing the storage type of this object. Can be one of the following: +<ul> +<li><em>Normal</em> is an object that lives only in the database.</li> +<li><em>Overridden</em> is an object that lives in the database and is overriding the exported configuration of a corresponding object in code.</li> +<li><em>Default</em> is an object that lives only in code.</li> +</ul> +<i>Note: This key can be changed by setting 'export type string' to something else, to try and prevent "type" from conflicting.</i> +</dd> +</dl> + +<h3>The load callback</h3> +Calling ctools_export_crud_load($table, $name) will invoke your load callback, and calling ctools_export_crud_load_all($table, $reset) will invoke your load all callback. The default handlers should be sufficient for most uses. + +Typically, there will be two load functions. A 'single' load, to load just one object, and an 'all' load, to load all of the objects for use in administrating the objects or utilizing the objects when you need all of them. Using ctools_export_load_object() you can easily do both, as well as quite a bit in between. This example duplicates the default functionality for loading one myobj. + +<pre> +/** +* Load a single myobj. +*/ +function mymodule_myobj_load($name) { + ctools_include('export'); + $result = ctools_export_load_object('mymodule_myobjs', 'names', array($name)); + if (isset($result[$name])) { + return $result[$name]; + } +} +</pre> + +<h3>The save callback</h3> +Calling ctools_export_crud_save($table, $object) will invoke your save callback. The default handlers should be sufficient for most uses. For the default save mechanism to work, you <b>must</b> define a 'primary key' in the 'export' section of your schema. The following example duplicates the default functionality for the myobj. + +<pre> +/** +* Save a single myobj. +*/ +function mymodule_myobj_save(&$myobj) { + $update = (isset($myobj->oid) && is_numeric($myobj->oid)) ? array('oid') : array(); + return drupal_write_record('myobj', $myobj, $update); +} +</pre> + +<h3>Default hooks for your exports</h3> +All exportables come with a 'default' hook, which can be used to put your exportable into code. The easiest way to actually use this hook is to set up your exportable for bulk exporting, enable the bulk export module and export an object. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/form.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/form.html new file mode 100644 index 0000000000000000000000000000000000000000..8b3adef207af85996e25927fa34bbf1c5a9cb14e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/form.html @@ -0,0 +1,35 @@ +CTools' form tool is a replacement for drupal_get_form() that includes some additional functionality: +<ul> +<li> It takes $form_state as an argument, which is accepted as a reference; meaning when the form is complete, you can examine the $form_state to see what the form did.</li> +<li> It can handle $_GET as an input source, or the input can be provided from some other source.</li> +<li> It can be told not to render or not to redirect, which can be important during AJAX operations.</li> +<li> It can provide a special 'wrapper' form which is used by the wizard tool to provide a standard set of buttons to a form.</li> +</ul> + +Usage: + +<pre> +ctools_include('form'); +$output = ctools_build_form($form_id, $form_state); +</pre> + +Previously, arguments to the form builder were passed into drupal_get_form; this is no longer true. You have two options for passing arguments to the form with ctools_build_form: set $form_state['args'] to an array which will then be passed to the builder as before. Or simply set $form_state values and refer to them in the builder. + +<h3>Values you can set on $form_state</h3> + +<dl> +<dt>no_redirect</dt> +<dd>If set to TRUE, completely disables redirecting, no matter what $form_state['redirect'] has been set to.</dd> +<dt>rerender</dt> +<dd>Defaults to TRUE. If set, the form will be rerendered after submit if not redirected. If set to FALSE the form will not be rerendered after submit and $output will be NULL.</dd> +<dt>method</dt> +<dd>Defaults to 'post'. May be set to 'get'. If 'get' is in use, form ids and tokens will not be used, and all get forms will automatically be assumed to be submitted. Beware as this can have unexpected effects on default values as fapi doesn't quite know how to handle this state.</dd> +<dt>input</dt> +<dd>Defaults to $_POST. If using 'get' you should set this to $_GET.</dd> +<dt>wrapper callback</dt> +<dd>If this is set to a function name, the form will be 'wrapped' in another form. This changes how the builder callback work! First, $form is set to a blank array. Then the wrapper callback is called with &$form and &$form_state as arguments. Then the form builder is called with &$form and &$form_state as arguments. No other arguments are given.</dd> +<dt>args</dt> +<dd>An array of arguments that will be passed to the form builder callback just as though they were passed as arguments to drupal_get_form().</dd> +<dt>want form</dt> +<dd>Defaults to FALSE. If set, instead of rendering, the return value will be the $form array. It can then be rendered via drupal_render() normally. This is particularly useful for AJAX operations that may need to process a form and then only render a part of it.</dd> +</dl> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/modal.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/modal.html new file mode 100644 index 0000000000000000000000000000000000000000..08388a0cd477e458d284e9a275bdb9ecfe192a4c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/modal.html @@ -0,0 +1,219 @@ +CTools provides a simple modal that can be used as a popup to place forms. It differs from the normal modal frameworks in that it does not do its work via an iframe. This is both an advantage and a disadvantage. The iframe simply renders normal pages in a sub-browser and they can do their thing. That makes it much easier to put arbitrary pages and forms in a modal. However, the iframe is not very good at actually communicating changes to the main page, so you cannot open the modal, have it do some work, and then modify the page. + +<h3>Invoking the modal</h3> + +The basic form of the modal can be set up just by including the javascript and adding the proper class to a link or form that will open the modal. To include the proper javascript, simply include the library and call the add_js function: + +<pre> +ctools_include('modal'); +ctools_modal_add_js(); +</pre> + +You can have links and buttons bound to use the modal by adding the class ctools-use-modal. For convenience, there is a helper function to try and do this, though it's not great at doing all links so using this is optional: + +<pre> +/** + * Render an image as a button link. This will automatically apply an AJAX class + * to the link and add the appropriate javascript to make this happen. + * + * @param $image + * The path to an image to use that will be sent to theme('image') for rendering. + * @param $dest + * The destination of the link. + * @param $alt + * The alt text of the link. + * @param $class + * Any class to apply to the link. @todo this should be a options array. + */ +function ctools_modal_image_button($image, $dest, $alt, $class = '') { + return ctools_ajax_text_button(theme('image', $image), $dest, $alt, $class, 'ctools-use-modal'); +} + +/** + * Render text as a link. This will automatically apply an AJAX class + * to the link and add the appropriate javascript to make this happen. + * + * Note: 'html' => true so be sure any text is vetted! Chances are these kinds of buttons will + * not use user input so this is a very minor concern. + * + * @param $image + * The path to an image to use that will be sent to theme('image') for rendering. + * @param $dest + * The destination of the link. + * @param $alt + * The alt text of the link. + * @param $class + * Any class to apply to the link. @todo this should be a options array. + */ +function ctools_modal_text_button($text, $dest, $alt, $class = '') { + return ctools_ajax_text_button($text, $dest, $alt, $class, 'ctools-use-modal'); +} +</pre> + +Like with all CTools' AJAX functionality, the href of the link will be the destination, with any appearance of /nojs/ converted to /ajax/. + + +For submit buttons, however, the URL may be found a different, slightly more complex way. If you do not wish to simply submit the form to the modal, you can create a URL using hidden form fields. The ID of the item is taken and -url is appended to it to derive a class name. Then, all form elements that contain that class name are founded and their values put together to form a URL. + +For example, let's say you have an 'add' button, and it has a select form item that tells your system what widget it is adding. If the id of the add button is edit-add, you would place a hidden input with the base of your URL in the form and give it a class of 'edit-add-url'. You would then add 'edit-add-url' as a class to the select widget allowing you to convert this value to the form without posting. If no URL is found, the action of the form will be used and the entire form posted to it. + +<h3>Customizing the modal</h3> + +If you do not wish to use the default modal, the modal can be customized by creating an array of data to define a customized modal. To do this, you add an array of info to the javascript settings to define the customizations for the modal and add an additional class to your modal link or button to tell it which modal to use. + +First, you need to create a settings array. You can do this most easily with a bit of PHP: + +<pre> + drupal_add_js(array( + 'my-modal-style' => array( + 'modalSize' => array( + 'type' => 'fixed', + 'width' => 250, + 'height' => 250, + ), + ), + ), 'setting'); +</pre> + +The key to the array above (in this case, my-modal-style) is the identifier to your modal theme. You can have multiple modal themes on a page, so be sure to use an ID that will not collide with some other module's use. Using your module or theme as a prefix is a good idea. + +Then, when adding the ctools-use-modal class to your link or button, also add the following class: ctools-modal-ID (in the example case, that would be ctools-modal-my-modal-style). + +modalSize can be 'fixed' or 'scale'. If fixed it will be a raw pixel value; if 'scale' it will be a percentage of the screen. + +You can set: +<ul> +<li> <b>modalSize</b>: an array of data to control the sizing of the modal. It can contain: +<ul> +<li> <b>type</b>: Either <i>fixed</i> or <i>scale</i>. If fixed, the modal will always be a fixed size. If <i>scale</i> the modal will scale to a percentage of the browser window. <i>Default: scale</i>. +<li> <b>width</b>: If <i>fixed</i> the width in pixels. If <i>scale</i> the percentage of the screen expressed as a number less than zero. (For 80 percent, use .8, for example). <i>Default: .8</i></li> +<li> <b>height</b>: If <i>fixed</i> the height in pixels. If <i>scale</i> the percentage of the screen expressed as a number less than zero. (For 80 percent, use .8, for example). <i>Default: .8</i></li> +<li> <b>addWidth</b>: Any additional width to add to the modal in pixels. Only useful if the type is scale. <i>Default: 0</i></li> +<li> <b>addHeight</b>: Any additional height to add to the modal in pixels. Only useful if the type is scale. <i>Default: 0</i></li> +<li> <b>contentRight</b>: The number of pixels to remove from the content inside the modal to make room for scroll bar and decorations. <i>Default: 25</i></li> +<li> <b>contentBottom</b>: The number of pixels to remove from the content inside the modal to make room for scroll bar and decorations. <i>Default: 45</i></li> +</ul> +</li> +<li> <b>modalTheme</b>: The Drupal javascript themable function which controls how the modal will be rendered. This function must be in the <i>Drupal.theme.prototype</i> namespace. If you set this value, you must include a corresponding function in a javascript file and use drupal_add_js() to add that file. <i>Default: CToolsModalDialog</i> +<pre> + Drupal.theme.prototype.CToolsModalDialog = function () { + var html = '' + html += ' <div id="ctools-modal">' + html += ' <div class="ctools-modal-content">' // panels-modal-content + html += ' <div class="modal-header">'; + html += ' <a class="close" href="#">'; + html += Drupal.CTools.Modal.currentSettings.closeText + Drupal.CTools.Modal.currentSettings.closeImage; + html += ' </a>'; + html += ' <span id="modal-title" class="modal-title"> </span>'; + html += ' </div>'; + html += ' <div id="modal-content" class="modal-content">'; + html += ' </div>'; + html += ' </div>'; + html += ' </div>'; + + return html; + } +</pre></li> +<li> <b>throbberTheme</b>: The Drupal javascript themable function which controls how the modal throbber will be rendered. This function must be in the <i>Drupal.theme.prototype</i> namespace. If you set this value, you must include a corresponding function in a javascript file and use drupal_add_js() to add that file. <i>Default: CToolsModalThrobber</i> +<pre> + Drupal.theme.prototype.CToolsModalThrobber = function () { + var html = ''; + html += ' <div id="modal-throbber">'; + html += ' <div class="modal-throbber-wrapper">'; + html += Drupal.CTools.Modal.currentSettings.throbber; + html += ' </div>'; + html += ' </div>'; + + return html; + }; +</pre> +</li> +<li> <b>modalOptions</b>: The options object that's sent to Drupal.CTools.Modal.modalContent. Can contain any CSS settings that will be applied to the modal backdrop, in particular settings such as <b>opacity</b> and <b>background</b>. <i>Default: array('opacity' => .55, 'background' => '#fff');</i></li> +<li> <b>animation</b>: Controls how the modal is animated when it is first drawn. Either <b>show</b>, <b>fadeIn</b> or <b>slideDown</b>. <i>Default: show</i></li> +<li> <b>animationSpeed</b>: The speed of the animation, expressed either as a word jQuery understands (slow, medium or fast) or a number of milliseconds for the animation to run. <i>Defaults: fast</i></li> +<li><b>closeText</b>: The text to display for the close button. Be sure to wrap this in t() for translatability. <i>Default: t('Close window')</i></li> +<li><b>closeImage</b>: The image to use for the close button of the modal. <i>Default: theme('image', ctools_image_path('icon-close-window.png'), t('Close window'), t('Close window'))</i></li> +<li><b>loadingText</b>: The text to display for the modal title during loading, along with the throbber. Be sure to wrap this in t() for translatability. <i>Default: t('Close window')</i></li> +<li><b>throbber</b>: The HTML to display for the throbber image. You can use this instead of CToolsModalThrobber theme if you just want to change the image but not the throbber HTML. <i>Default: theme('image', ctools_image_path('throbber.gif'), t('Loading...'), t('Loading'))</i></li> +<li> +</ul> + +<h3>Rendering within the modal</h3> +To render your data inside the modal, you need to provide a page callback in your module that responds more or less like a normal page. + +In order to handle degradability, it's nice to allow your page to work both inside and outside of the modal so that users whose javascript is turned off can still use your page. There are two ways to accomplish this. First, you can embed 'nojs' as a portion of the URL and then watch to see if that turns into 'ajax' when the link is clicked. Second, if you do not wish to modify the URLs, you can check $_POST['js'] or $_POST['ctools_js'] to see if that flag was set. The URL method is the most flexible because it is easy to send the two links along completely different paths if necessary, and it is also much easier to manually test your module's output by manually visiting the nojs URL. It's actually quite difficult to do this if you have to set $_POST['js'] to test. + +In your hook_menu, you can use the a CTools' AJAX convenience loader to help: + +<pre> + $items['ctools_ajax_sample/%ctools_js/login'] = array( + 'title' => 'Login', + 'page callback' => 'ctools_ajax_sample_login', + 'page arguments' => array(1), + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); +</pre> + +The first argument to the page callback will be the result of ctools_js_load() which will return TRUE if 'ajax' was the string, and FALSE if anything else (i.e, nojs) is the string. Which means you can then declare your function like this: + +<pre> +function ctools_ajax_sample_login($js) { + if ($js) { + // react with the modal + } + else { + // react without the modal + } +} +</pre> + +If your modal does not include a form, rendering the output you wish to give the user is just a matter of calling the modal renderer with your data: + +<pre> +function ctools_ajax_hello_world($js) { + $title = t('Greetings'); + $output = '<p>' . t('Hello world') . ''</p>'; + if ($js) { + ctools_modal_render($title, $output); + } + else { + drupal_set_title($title); + return $output; + } +} +</pre> + +If you need to do more than just render your modal, you can use a CTools $commands array. See the function ctools_modal_render() for more information on what you need to do here. + +If you are displaying a form -- and the vast majority of modals display forms -- then you need to do just slightly more. Fortunately there is the ctools_modal_form_wrapper() function: + +<pre> + ctools_include('modal'); + ctools_include('ajax'); + $form_state = array( + 'title' => t('Title of my form'), + 'ajax' => $js, + ); + $output = ctools_modal_form_wrapper('my_form', $form_state); + // There are some possible states after calling the form wrapper: + // 1) We are not using $js and there is form output to be rendered. + // 2) We are using $js and the form was successfully submitted and + // we need to dismiss the modal. + // Most other states are handled automatically unless you set flags in + // $form_state to avoid handling them, so we only deal with those two + // states. + if (empty($output) && $js) { + $commands = array(); + $commands[] = ctools_modal_command_dismiss(t('Login Success'); + // In typical usage you will do something else here, such as update a + // div with HTML or redirect the page based upon the results of the modal + // form. + ctools_ajax_render($commands); + } + + // Otherwise, just return the output. + return $output; +</pre> + +You can also use CTools' form wizard inside the modal. You do not need to do much special beyond setting $form_state['modal'] = TRUE in the wizard form; it already knows how to handle the rest. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/object-cache.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/object-cache.html new file mode 100644 index 0000000000000000000000000000000000000000..964817085534abfe5d1a700f9ef39324b7ab6cb3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/object-cache.html @@ -0,0 +1,132 @@ +The CTools Object Cache is a specialized cache for storing data that is non-volatile. This differs from the standard Drupal cache mechanism, which is volatile, meaning that the data can be cleared at any time and it is expected that any cached data can easily be reconstructed. In contrast, data stored in this cache is not expected to be reconstructable. It is primarily used for storing user input which is retrieved in stages, allowing for more complex user interface interactions. + +The object cache consists of 3 normal functions for cache maintenance, and 2 additional functions to facilitate locking. + +To use any of these functions, you must first use ctools_include: + +<pre> +ctools_include('object-cache'); +</pre> + +<pre> +/** + * Get an object from the non-volatile ctools cache. + * + * This function caches in memory as well, so that multiple calls to this + * will not result in multiple database reads. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being stored. + * @param $skip_cache + * Skip the memory cache, meaning this must be read from the db again. + * + * @return + * The data that was cached. + */ +function ctools_object_cache_get($obj, $name, $skip_cache = FALSE) { +</pre> + +<pre> +/** + * Store an object in the non-volatile ctools cache. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being stored. + * @param $cache + * The object to be cached. This will be serialized prior to writing. + */ +function ctools_object_cache_set($obj, $name, $cache) { +</pre> + +<pre> +/** + * Remove an object from the non-volatile ctools cache + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being removed. + */ +function ctools_object_cache_clear($obj, $name) { +</pre> + +To facilitate locking, which is the ability to prohibit updates by other users while one user has an object cached, this system provides two functions: + +<pre> +/** + * Determine if another user has a given object cached. + * + * This is very useful for 'locking' objects so that only one user can + * modify them. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being removed. + * + * @return + * An object containing the UID and updated date if found; NULL if not. + */ +function ctools_object_cache_test($obj, $name) { +</pre> + +The object returned by ctools_object_cache_test can be directly used to determine whether a user should be allowed to cache their own version of an object. + +To allow the concept of breaking a lock, that is, clearing another users changes: + +<pre> +/** + * Remove an object from the non-volatile ctools cache for all session IDs. + * + * This is useful for clearing a lock. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being removed. + */ +function ctools_object_cache_clear_all($obj, $name) { +</pre> + +Typical best practice is to use wrapper functions such as these: + +<pre> +/** + * Get the cached changes to a given task handler. + */ +function delegator_page_get_page_cache($name) { + ctools_include('object-cache'); + $cache = ctools_object_cache_get('delegator_page', $name); + if (!$cache) { + $cache = delegator_page_load($name); + $cache->locked = ctools_object_cache_test('delegator_page', $name); + } + + return $cache; +} + +/** + * Store changes to a task handler in the object cache. + */ +function delegator_page_set_page_cache($name, $page) { + ctools_include('object-cache'); + $cache = ctools_object_cache_set('delegator_page', $name, $page); +} + +/** + * Remove an item from the object cache. + */ +function delegator_page_clear_page_cache($name) { + ctools_include('object-cache'); + ctools_object_cache_clear('delegator_page', $name); +} +</pre> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-api.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-api.html new file mode 100644 index 0000000000000000000000000000000000000000..47e5d6bad3bf9b4db1a37ace04ec0b86f7006368 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-api.html @@ -0,0 +1,54 @@ +APIs are a form of plugins that are tightly associated with a module. Instead of a module providing any number of plugins, each module provides only one file for an API and this file can contain hooks that the module should invoke. + +Modules support this API by implementing hook_ctools_plugin_api($module, $api). If they support the API, they return a packet of data: +<pre> +function mymodule_ctools_plugin_api($module, $api) { + if ($module == 'some module' && $api = 'some api') { + return array( + 'version' => The minimum API version this system supports. If this API version is incompatible then the .inc file will not be loaded. + 'path' => Where to find the file. Optional; if not specified it will be the module's directory. + 'file' => an alternative version of the filename. If not specified it will be $module.$api.inc + ); + } +} +</pre> + +This implementation must be in the .module file. + +Modules utilizing this can invole ctools_plugin_api_include() in order to ensure all modules that support the API will have their files loaded as necessary. It's usually easiest to create a small helper function like this: + +<pre> +define('MYMODULE_MINIMUM_VERSION', 1); +define('MYMODULE_VERSION', 1); + +function mymodule_include_api() { + ctools_include('plugins'); + return ctools_plugin_api_include('mymodule', 'myapi', MYMODULE_MINIMUM_VERSION, MYMODULE_VERSION); +} +</pre> + +Using a define will ensure your use of version numbers is consistent and easy to update when you make API changes. You can then use the usual module_invoke type commands: + +<pre> +mymodule_include_api(); +module_invoke('myhook', $data); +</pre> + +If you need to pass references, this construct is standard: + +<pre> +foreach (mymodule_include_api() as $module => $info) { + $function = $module . '_hookname'; + // Just because they implement the API and include a file does not guarantee they implemented + // a hook function! + if (!function_exists($function)) { + continue; + } + + // Typically array_merge() is used below if data is returned. + $result = $function($data1, $data2, $data3); +} +</pre> + +TODO: There needs to be a way to check API version without including anything, as a module may simply +provide normal plugins and versioning could still matter. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-creating.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-creating.html new file mode 100644 index 0000000000000000000000000000000000000000..77f0315cdd607d7ec10ab468448994200c6a9d78 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-creating.html @@ -0,0 +1,189 @@ +There are two primary pieces to using plugins. The first is getting the data, and the second is using the data. + +<h3>Getting the data</h3> +To create a plugin, a module only has to execute ctools_get_plugins with the right data: + +<pre> + ctools_include('plugins'); + ctools_get_plugins($module, $type, [$id]) +</pre> + +In the above example, $module should be your module's name and $type is the type of the plugin. It is typically best practice to provide some kind of wrapper function to make this easier. For example, Panels provides the following functions to implement the 'content_types' plugin: + +<pre> +/** + * Fetch metadata on a specific content_type plugin. + * + * @param $content type + * Name of a panel content type. + * + * @return + * An array with information about the requested panel content type. + */ +function panels_get_content_type($content_type) { + ctools_include('context'); + ctools_include('plugins'); + return ctools_get_plugins('panels', 'content_types', $content_type); +} + +/** + * Fetch metadata for all content_type plugins. + * + * @return + * An array of arrays with information about all available panel content types. + */ +function panels_get_content_types() { + ctools_include('context'); + ctools_include('plugins'); + return ctools_get_plugins('panels', 'content_types'); +} +</pre> + +As a plugin creator, your module can also implement a hook to give more information about this plugin, and to enable a few features that are not normally enabled. If you need any of these features, simply implement hook_ctools_plugin_TYPE (where TYPE is the same $type sent to ctools_get_plugins). This isn't a true hook, it will only be called for the $module that was given. This hook returns an array: + +<pre> +/** + * Inform CTools that the layout plugin can be loaded from themes. + */ +function panels_ctools_plugin_layouts() { + return array( + 'load themes' => TRUE, + ); +} +</pre> + +The following information can be specified: +<dl> +<dt>cache</dt> +<dd><em>Defaults to:</em> <strong>FALSE</strong></dd> +<dd>If set to TRUE, the results of ctools_get_plugins will be cached in the 'cache' table (by default), thus preventing .inc files from being loaded. ctools_get_plugins looking for a specific plugin will always load the appropriate .inc file.</dd> +<dt>cache table</dt> +<dd><em>Defaults to:</em> <strong>'cache'</strong></dd> +<dd>If 'cache' is TRUE, then this value specifies the cache table where the cached plugin information will be stored.</dd> +<dt>defaults</dt> +<dd><em>Defaults to:</em> <strong>array()</strong></dd> +<dd>An array of defaults that should be added to each plugin; this can be used to ensure that every plugin has the basic data necessary. These defaults will not ovewrite data supplied by the plugin. This could also be a function name, in which case the callback will be used to provide defaults. NOTE, however, that the callback-based approach is deprecated as it is redundant with the 'process' callback, and as such will be removed in later versions. Consequently, you should only use the array form for maximum cross-version compatibility.</dd> +<dt>load themes</dt> +<dd><em>Defaults to:</em> <strong>FALSE</strong></dd> +<dd>If set to TRUE, then plugins of this type can be supplied by themes as well as modules. If this is the case, all themes that are currently enabled will provide a plugin: NOTE: Due to a slight UI bug in Drupal, it is possible for the default theme to be active but not enabled. If this is the case, that theme will NOT provide plugins, so if you are using this feature, be sure to document that issue. Also, themes set via $custom_theme do not necessarily need to be enabled, but the system has no way of knowing what those themes are, so the enabled flag is the only true method of identifying which themes can provide layouts.</dd> +<dt>hook</dt> +<dd><em>Defaults to:</em> (dynamic value)</dd> +<dd>The name of the hook used to collect data for this plugin. Normally this is <strong>$module . '_' . $type</strong> -- but this can be changed here. If you change this, you MUST be sure to document this for your plugin implementors as it will change the format of the specially named hook. +<dt>process</dt> +<dd><em>Defaults to:</em> <strong>''</strong></dd> +<dd>An optional function callback to use for processing a plugin. This can be used to provide automated settings that must be calculated per-plugin instance (i.e., it is not enough to simply append an array via 'defaults'). The parameters on this callback are: <strong>callback(&$plugin, $info)</strong> where $plugin is a reference to the plugin as processed and $info is the fully processed result of hook_ctools_plugin_api_info(). +<dt>extension</dt> +<dd><em>Defaults to:</em> <strong>'inc'</strong></dd> +<dd>Can be used to change the extension on files containing plugins of this type. By default the extension will be "inc", though it will default to "info" if "info files" is set to true. Do not include the dot in the extension if changing it, that will be added automatically.</dd> +<dt>info file</dt> +<dd><em>Defaults to:</em> <strong>FALSE</strong></dd> +<dd>If set to TRUE, then the plugin will look for a .info file instead of a .inc. Internally, this will look exactly the same, though obviously a .info file cannot contain functions. This can be good for styles that may not need to contain code.</dd> +<dt>use hooks</dt> +<dd><em>Defaults to:</em> <strong>TRUE</strong>*</dd> +<dd>Use to enable support for plugin definition hooks instead of plugin definition files. NOTE: using a central plugin definition hook is less optimal for the plugins system, and as such this will default to FALSE in later versions.</dd> +<dt>child plugins</dt> +<dd><em>Defaults to:</em> <strong>FALSE</strong></dd> +<dd>If set to TRUE, the plugin type can automatically have 'child plugins' meaning each plugin can actually provide multiple plugins. This is mostly used for plugins that store some of their information in the database, such as views, blocks or exportable custom versions of plugins.</dd> +<dd>To implement, each plugin can have a 'get child' and 'get children' callback. Both of these should be implemented for performance reasons, since it is best to avoid getting all children if necessary, but if 'get child' is not implemented, it will fall back to 'get children' if it has to.</dd> +<dd>Child plugins should be named parent:child, with the : being the separator, so that it knows which parent plugin to ask for teh child. The 'get children' method should at least return the parent plugin as part of the list, unless it wants the parent plugin itself to not be a choosable option, which is not unheard of. </dd> +<dd>'get children' arguments are ($plugin, $parent) and 'get child' arguments are ($plugin, $parent, $child). +</dl> + +In addition, there is a 'module' and 'type' settings; these are for internal use of the plugin system and you should not change these. + +<h3>Using the data</h3> + +Each plugin returns a packet of data, which is added to with a few defaults. Each plugin is guaranteed to always have the following data: +<dl> +<dt>name</dt> +<dd>The name of the plugin. This is also the key in the array, of the full list of plugins, and is placed here since that is not always available.</dd> +<dt>module</dt> +<dd>The module that supplied the plugin.</dd> +<dt>file</dt> +<dd>The actual file containing the plugin.</dd> +<dt>path</dt> +<dd>The path to the file containing the plugin. This is useful for using secondary files, such as templates, css files, images, etc, that may come with a plugin.</dd> +</dl> + +Any of the above items can be overridden by the plugin itself, though the most likely one to be modified is the 'path'. + +The most likely data (beyond simple printable data) for a plugin to provide is a callback. The plugin system provides a pair of functions to make it easy and consistent for these callbacks to be used. The first is ctools_plugin_get_function, which requires the full $plugin object. + +<pre> +/** + * Get a function from a plugin, if it exists. If the plugin is not already + * loaded, try ctools_plugin_load_function() instead. + * + * @param $plugin + * The loaded plugin type. + * @param $callback_name + * The identifier of the function. For example, 'settings form'. + * + * @return + * The actual name of the function to call, or NULL if the function + * does not exist. + */ +function ctools_plugin_get_function($plugin, $callback_name) +</pre> + +The second does not require the full $plugin object, and will load it: +<pre> +/** + * Load a plugin and get a function name from it, returning success only + * if the function exists. + * + * @param $module + * The module that owns the plugin type. + * @param $type + * The type of plugin. + * @param $id + * The id of the specific plugin to load. + * @param $callback_name + * The identifier of the function. For example, 'settings form'. + * + * @return + * The actual name of the function to call, or NULL if the function + * does not exist. + */ +function ctools_plugin_load_function($module, $type, $id, $callback_name) { +</pre> + +Both of these functions will ensure any needed files are included. In fact, it allows each callback to specify alternative include files. The plugin implementation could include code like this: + +<pre> + 'callback_name' => 'actual_name_of_function_here', +</pre> + +Or like this: +<pre> + 'callback_name' => array( + 'file' => 'filename', + 'path' => 'filepath', // optional, will use plugin path if absent + 'function' => 'actual_name_of_function_here', + ), +</pre> + +An example, for 'plugin_example' type + +<pre> +$plugin = array( + 'name' => 'my_plugin', + 'module' => 'my_module', + 'example_callback' => array( + 'file' => 'my_plugin.extrafile.inc', + 'function' => 'my_module_my_plugin_example_callback', + ), +); +</pre> + +To utilize this callback on this plugin: + +<pre> +if ($function = ctools_plugin_get_function($plugin, 'example_callback')) { + $function($arg1, $arg2, $etc); +} +</pre> + +<h3>Document your plugins!</h3> +Since the data provided by your plugin tends to be specific to your plugin type, you really need to document what the data returned in the hook in the .inc file will be or nobody will figure it out. Use advanced help and document it there. If every system that utilizes plugins does this, then plugin implementors will quickly learn to expect the documentation to be in the advanced help. + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-implementing.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-implementing.html new file mode 100644 index 0000000000000000000000000000000000000000..0ea1269ee38ce8b11aaf9353ae8f94b7eda8979b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins-implementing.html @@ -0,0 +1,58 @@ +To implement plugins, you need to implement a single hook in your module to tell the system where your plugins live, and then you need to implement one or more .inc files that contain the plugin data. + +<h3>Telling it where your plugins live</h3> +To implement any plugins at all, you must implement a single function for all plugins: <strong>hook_ctools_plugin_directory</strong>. Every time a module loads plugins, this hook will be called to see which modules implement those plugins and in what directory those plugins will live. + +<pre> +function hook_ctools_plugin_directory($module, $plugin) { + if ($module == 'panels' && $plugin == 'content_types') { + return 'plugins/content_types'; + } +} +</pre> + +The directory returned should be relative to your module. Another common usage is to simply return that you implement all plugins owned by a given module (or modules): + +<pre> +function hook_ctools_plugin_directory($module, $plugin) { + if ($module == 'panels') { + return 'plugins/' . $plugin; + } +} +</pre> + +Typically, it is recommended that all plugins be placed into the 'plugins' directory for clarity and maintainability. Inside the directory, any number of subdirectories can be used. For plugins that require extra files, such as templates, css, javascript or image files, this is highly recommended: +<pre> +mymodule.module +mymodule.info +plugins/ + content_types/ + my_content_type.inc + layouts/ + my_layout.inc + my_laout.css + my_layout.tpl.php + my_layout_image.png +</pre> + +<h3>How a theme can implement plugins</h3> +Themes can implement plugins if the plugin owner specified that it's possible in its hook_ctools_api_TYPE() call. If so, it is generally exactly the same as modules, except for one important difference: themes don't get hook_ctools_plugin_directory(). Instead, themes add a line to their info file: + +<pre> +plugins[module][type] = directory +</pre> + +<h3>How to structure the .inc file</h3> + +The top of the .inc file should contain an array that defines the plugin. This array is simply defined in the global namespace of the file and does not need a function. Note that previous versions of this plugin system required a specially named function. While this function will still work, its use is now discouraged, as it is annoying to name properly. + +This array should look something like this: +<pre> +$plugin = array( + 'key' => 'value', +); +</pre> + +Several values will be filled in for you automatically, but you can override them if necessary. They include 'name', 'path', 'file' and 'module'. Additionally, the plugin can owner can provide other defaults as well. + +After this array, if your plugin needs functions, they can be declared. Different plugin types have different needs here, so exactly what else will be needed will change from type to type. diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins.html new file mode 100644 index 0000000000000000000000000000000000000000..906813ee88fc1bfe11811f7ab13935a03dc1fe82 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/plugins.html @@ -0,0 +1,5 @@ +The plugins tool allows a module to allow <b>other</b> modules (and themes!) to provide plugins which provide some kind of functionality or some kind of task. For example, in Panels there are several types of plugins: Content types (which are like blocks), layouts (which are page layouts) and styles (which can be used to style a panel). Each plugin is represented by a .inc file, and the functionality they offer can differ wildly. + +A module which uses plugins can implement a hook describing the plugin (which is not necessary, as defaults will be filled in) and then calls a ctools function which loads either all the known plugins (used for listing/choosing) or loads a specific plugin (used when its known which plugin is needed). From the perspective of the plugin system, a plugin is a packet of data, usually some printable info and a list of callbacks. It is up to the module implementing plugins to determine what that info means and what the callbacks do. + +A module which implements plugins must first implement the <strong>hook_ctools_plugin_directory</strong> function, which simply tells the system which plugins are supported and what directory to look in. Each plugin will then be in a .inc file in the directory supplied. The .inc file will contain a specially named hook which returns the data necessary to implement the plugin. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/help/wizard.html b/drupal/sites/default/boinc/modules/contrib/ctools/help/wizard.html new file mode 100644 index 0000000000000000000000000000000000000000..5e4ebe8840244760da3ce8c04a0a327302bffa3b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/help/wizard.html @@ -0,0 +1,287 @@ +Form wizards, or multi-step forms, are a process by which the user goes through or can use an arbitrary number of different forms to create a single object or perform a single task. Traditionally the multi-step form is difficult in Drupal because there is no easy place to put data in between forms. No longer! The form wizard tool allows a single entry point to easily set up a wizard of multiple forms, provide callbacks to handle data storage and updates between forms and when forms are completed. This tool pairs well with the <a href="&topic:ctools/object-cache&">object cache</a> tool for storage. + +<h3>The form info array</h3> +The wizard starts with an array of data that describes all of the forms available to the wizard and sets options for how the wizard will present and control the flow. Here is an example of the $form_info array as used in the delegator module: + +<pre> + $form_info = array( + 'id' => 'delegator_page', + 'path' => "admin/build/pages/edit/$page_name/%step", + 'show trail' => TRUE, + 'show back' => TRUE, + 'show return' => FALSE, + 'next callback' => 'delegator_page_add_subtask_next', + 'finish callback' => 'delegator_page_add_subtask_finish', + 'return callback' => 'delegator_page_add_subtask_finish', + 'cancel callback' => 'delegator_page_add_subtask_cancel', + 'order' => array( + 'basic' => t('Basic settings'), + 'argument' => t('Argument settings'), + 'access' => t('Access control'), + 'menu' => t('Menu settings'), + 'multiple' => t('Task handlers'), + ), + 'forms' => array( + 'basic' => array( + 'form id' => 'delegator_page_form_basic' + ), + 'access' => array( + 'form id' => 'delegator_page_form_access' + ), + 'menu' => array( + 'form id' => 'delegator_page_form_menu' + ), + 'argument' => array( + 'form id' => 'delegator_page_form_argument' + ), + 'multiple' => array( + 'form id' => 'delegator_page_argument_form_multiple' + ), + ), + ); +</pre> + +The above array starts with an <b>id</b> which is used to identify the wizard in various places and a <b>path</b> which is needed to redirect to the next step between forms. It then creates some <b>settings</b> which control which pieces are displayed. In this case, it displays a form trail and a 'back' button, but not the 'return' button. Then there are the <b>wizard callbacks</b> which allow the wizard to act appropriately when forms are submitted. Finally it contains a <b>list of forms</b> and their <b>order</b> so that it knows which forms to use and what order to use them by default. Note that the keys in the order and list of forms match; that key is called the <b>step</b> and is used to identify each individual step of the wizard. + +Here is a full list of every item that can be in the form info array: + +<dl> +<dt>id</dt> +<dd>An id for wizard. This is used like a hook to automatically name <b>callbacks</b>, as well as a form step's form building function. It is also used in trail theming.</dd> +<dt>path</dt> +<dd>The path to use when redirecting between forms. <strong>%step</strong> will be replaced with the key for the form.</dd> +<dt>return path</dt> +<dd>When a form is complete, this is the path to go to. This is required if the 'return' button is shown and not using AJAX. It is also used for the 'Finish' button. If it is not present and needed, the cancel path will also be checked.</dd> +<dt>cancel path</dt> +<dd>When a form is canceled, this is the path to go to. This is required if the 'cancel' is shown and not using AJAX.</dd> +<dt>show trail</dt> +<dd>If set to TRUE, the form trail will be shown like a breadcrumb at the top of each form. Defaults to FALSE.</dd> +<dt>show back</dt> +<dd>If set to TRUE, show a back button on each form. Defaults to FALSE.</dd> +<dt>show return</dt> +<dd>If set to TRUE, show a return button. Defaults to FALSE.</dd> +<dt>show cancel</dt> +<dd>If set to TRUE, show a cancel button. Defaults to FALSE.</dd> +<dt>back text</dt> +<dd>Set the text of the 'back' button. Defaults to t('Back').</dd> +<dt>next text</dt> +<dd>Set the text of the 'next' button. Defaults to t('Continue').</dd> +<dt>return text</dt> +<dd>Set the text of the 'return' button. Defaults to t('Update and return').</dd> +<dt>finish text</dt> +<dd>Set the text of the 'finish' button. Defaults to t('Finish').</dd> +<dt>cancel text</dt> +<dd>Set the text of the 'cancel' button. Defaults to t('Cancel').</dd> +<dt>ajax</dt> +<dd>Turn on AJAX capabilities, using CTools' ajax.inc. Defaults to FALSE.</dd> +<dt>modal</dt> +<dd>Put the wizard in the modal tool. The modal must already be open and called from an ajax button for this to work, which is easily accomplished using functions provided by the modal tool.</dd> +<dt>ajax render</dt> +<dd>A callback to display the rendered form via ajax. This is not required if using the modal tool, but is required otherwise since ajax by itself does not know how to render the results. Params: &$form_state, $output.</dd> +<dt>finish callback</dt> +<dd> +The function to call when a form is complete and the finish button has been clicked. This function should finalize all data. Params: &$form_state. +Defaults to $form_info['id']._finish if function exists. +</dd> +<dt>cancel callback</dt> +<dd> +The function to call when a form is canceled by the user. This function should clean up any data that is cached. Params: &$form_state. +Defaults to $form_info['id']._cancel if function exists.</dd> +<dt>return callback</dt> +<dd> +The function to call when a form is complete and the return button has been clicked. This is often the same as the finish callback. Params: &$form_state. +Defaults to $form_info['id']._return if function exists.</dd> +<dt>next callback</dt> +<dd> +The function to call when the next button has been clicked. This function should take the submitted data and cache it for later use by the finish callback. Params: &$form_state. +Defaults to $form_info['id']._next if function exists.</dd> +<dt>order</dt> +<dd>An optional array of forms, keyed by the step, which represents the default order the forms will be displayed in. If not set, the forms array will control the order. Note that submit callbacks can override the order so that branching logic can be used.</dd> +<dt>forms</dt> +<dd>An array of form info arrays, keyed by step, describing every form available to the wizard. If order array isn't set, the wizard will use this to set the default order. Each array contains: + <dl> + <dt>form id</dt> + <dd> + The id of the form, as used in the Drupal form system. This is also the name of the function that represents the form builder. + Defaults to $form_info['id']._.$step._form. + </dd> + <dt>include</dt> + <dd>The name of a file to include which contains the code for this form. This makes it easy to include the form wizard in another file or set of files. This must be the full path of the file, so be sure to use drupal_get_path() when setting this. This can also be an array of files if multiple files need to be included.</dd> + <dt>title</dt> + <dd>The title of the form, to be optionally set via drupal_get_title. This is required when using the modal if $form_state['title'] is not set.</dd> + </dl> +</dd> +</dl> + +<h3>Invoking the form wizard</h3> +Your module should create a page callback via hook_menu, and this callback should contain an argument for the step. The path that leads to this page callback should be the same as the 'path' set in the $form_info array. + +The page callback should set up the $form_info, and figure out what the default step should be if no step is provided (note that the wizard does not do this for you; you MUST specify a step). Then invoke the form wizard: + +<pre> + $form_state = array(); + ctools_include('wizard'); + $output = ctools_wizard_multistep_form($form_info, $step, $form_state); +</pre> + +If using AJAX or the modal, This part is actually done! If not, you have one more small step: +<pre> + return $output; +</pre> + +<h3>Forms and their callbacks</h3> +Each form within the wizard is a complete, independent form using Drupal's Form API system. It has a form builder callback as well as submit and validate callbacks and can be form altered. The primary difference between these forms and a normal Drupal form is that the submit handler should not save any data. Instead, it should make any changes to a cached object (usually placed on the $form_state) and only the _finish or _return handler should actually save any real data. + +How you handle this is completely up to you. The recommended best practice is to use the CTools Object cache, and a good way to do this is to write a couple of wrapper functions around the cache that look like these example functions: + +<pre> +/** + * Get the cached changes to a given task handler. + */ +function delegator_page_get_page_cache($name) { + ctools_include('object-cache'); + $cache = ctools_object_cache_get('delegator_page', $name); + if (!$cache) { + $cache = delegator_page_load($name); + $cache->locked = ctools_object_cache_test('delegator_page', $name); + } + + return $cache; +} + +/** + * Store changes to a task handler in the object cache. + */ +function delegator_page_set_page_cache($name, $page) { + ctools_include('object-cache'); + $cache = ctools_object_cache_set('delegator_page', $name, $page); +} + +/** + * Remove an item from the object cache. + */ +function delegator_page_clear_page_cache($name) { + ctools_include('object-cache'); + ctools_object_cache_clear('delegator_page', $name); +} +</pre> + +Using these wrappers, when performing a get_cache operation, it defaults to loading the real object. It then checks to see if another user has this object cached using the ctools_object_cache_test() function, which automatically sets a lock (which can be used to prevent writes later on). + +With this set up, the _next, _finish and _cancel callbacks are quite simple: + +<pre> +/** + * Callback generated when the add page process is finished. + */ +function delegator_page_add_subtask_finish(&$form_state) { + $page = &$form_state['page']; + + // Create a real object from the cache + delegator_page_save($page); + + // Clear the cache + delegator_page_clear_page_cache($form_state['cache name']); +} + +/** + * Callback generated when the 'next' button is clicked. + * + * All we do here is store the cache. + */ +function delegator_page_add_subtask_next(&$form_state) { + // Update the cache with changes. + delegator_page_set_page_cache($form_state['cache name'], $form_state['page']); +} + +/** + * Callback generated when the 'cancel' button is clicked. + * + * All we do here is clear the cache. + */ +function delegator_page_add_subtask_cancel(&$form_state) { + // Update the cache with changes. + delegator_page_clear_page_cache($form_state['cache name']); +} +</pre> + +All that's needed to tie this together is to understand how the changes made it into the cache in the first place. This happened in the various form _submit handlers, which made changes to $form_state['page'] based upon the values set in the form: + +<pre> +/** + * Store the values from the basic settings form. + */ +function delegator_page_form_basic_submit(&$form, &$form_state) { + if (!isset($form_state['page']->pid) && empty($form_state['page']->import)) { + $form_state['page']->name = $form_state['values']['name']; + } + + $form_state['page']->admin_title = $form_state['values']['admin_title']; + $form_state['page']->path = $form_state['values']['path']; +} +</pre> + +No database operations were made during this _submit, and that's a very important distinction about this system. + +<h3>Proper handling of back button</h3> +When using <strong>'show back' => TRUE</strong> the cached data should be assigned to the <em>#default_value</em> form property. Otherwise when the user goes back to the previous step the forms default values instead of his (cached) input is used. + +<pre> +/** + * Form builder function for wizard. + */ +function wizardid_step2_form(&$form, &$form_state) { + $form_state['my data'] = my_module_get_cache($form_state['cache name']); + $form['example'] = array( + '#type' => 'radios', + '#title' => t('Title'), + '#default_value' => $form_state['my data']->example ? $form_state['my data']->example : default, + '#options' => array( + 'default' => t('Default'), + 'setting1' => t('Setting1'), + ), + ); +} + +/** + * Submit handler to prepare needed values for storing in cache. + */ +function wizardid_step2_form_submit($form, &$form_state) { + $form_state['my data']->example = $form_state['values']['example']; +} +</pre> + +The data is stored in the <em>my data</em> object on submitting. If the user goes back to this step the cached <em>my data</em> is used as the default form value. The function <em>my_module_get_cache()</em> is like the cache functions explained above. + +<h3>Required fields, cancel and back buttons</h3> +If you have required fields in your forms, the back and cancel buttons will not work as expected since validation of the form will fail. You can add the following code to the top of your form validation to avoid this problem : +<pre> +/** + * Validation handler for step2 form + */ +function wizardid_step2_form_validate(&$form, &$form_state) { + // if the clicked button is anything but the normal flow + if ($form_state['clicked_button']['#next'] != $form_state['next']) { + drupal_get_messages('error'); + form_set_error(NULL, '', TRUE); + return; + } + // you form validation goes here + // ... +} +</pre> + +<h3>Wizard for anonymous users</h3> +If you are creating a wizard which is be used by anonymous users, you might run into some issues with drupal's caching for anonymous users. You can circumvent this by using hook_init and telling drupal to not cache your wizard pages : +<pre> +/** + * Implementation of hook init + */ +function mymodule_init() { + // if the path leads to the wizard + if (drupal_match_path($_GET['q'], 'path/to/your/wizard/*')) { + // set cache to false + $GLOBALS['conf']['cache'] = FALSE; + } +} +</pre> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/images/collapsible-collapsed.png b/drupal/sites/default/boinc/modules/contrib/ctools/images/collapsible-collapsed.png new file mode 100644 index 0000000000000000000000000000000000000000..95a214a6e6d17fee2f098804997f3826ffc9d4ca Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/images/collapsible-collapsed.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/images/collapsible-expanded.png b/drupal/sites/default/boinc/modules/contrib/ctools/images/collapsible-expanded.png new file mode 100644 index 0000000000000000000000000000000000000000..46f39ecb351cff65243fa9a614a69d039e1302a5 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/images/collapsible-expanded.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-close-window.png b/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-close-window.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0cf695b0cac487efecfd7eae66e7492a2ba306 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-close-window.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-configure.png b/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-configure.png new file mode 100644 index 0000000000000000000000000000000000000000..e23d67cc04b84880d0437e23ffcba837d2dc4121 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-configure.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-delete.png b/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0cf695b0cac487efecfd7eae66e7492a2ba306 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/images/icon-delete.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/images/no-icon.png b/drupal/sites/default/boinc/modules/contrib/ctools/images/no-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fa78ec179a83428e5b8e247890278cdf91a8cb3e Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/images/no-icon.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/images/status-active.gif b/drupal/sites/default/boinc/modules/contrib/ctools/images/status-active.gif new file mode 100644 index 0000000000000000000000000000000000000000..207e95c3fa8cc31a89af150ad74059b1667922b6 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/images/status-active.gif differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/images/throbber.gif b/drupal/sites/default/boinc/modules/contrib/ctools/images/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..8a084b8447d506e9b655ad52405cbf7a73034550 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/images/throbber.gif differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/ajax.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/ajax.inc new file mode 100644 index 0000000000000000000000000000000000000000..e560a28ad240a372cfb29547cd49c6b00f550dee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/ajax.inc @@ -0,0 +1,752 @@ +<?php + +// Set this so we can tell that the file has been included at some point. +define('CTOOLS_AJAX_INCLUDED', 1); + +/** + * @file + * Utilize the CTools AJAX responder. + * + * The AJAX responder is a javascript tool to make it very easy to do complicated + * operations as a response to AJAX requests. When links are attached to the ajax + * responder, the server sends back a packet of JSON data; this packet is an + * array of commands to carry out. + * + * The command names correlate to functions in the responder space, making it + * relatively easy for applications to provide their own commands to do whatever + * spiffy functionality is necessary. + * + * Each command is an object. $object->command is the type of command and + * will be used to find the function (it will correlate directly to + * a function in the Drupal.CTools.AJAX.Command space). The object can + * contain any other data that the command needs to process. + * + * Built in commands include: + * - replace + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * - data: The data to use with the jquery replace() function. + * + * - prepend + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * - data: The data to use with the jquery prepend() function. + * + * - append + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * - data: The data to use with the jquery append() function. + * + * - after + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * - data: The data to use with the jquery after() function. + * + * - before + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * - data: The data to use with the jquery before() function. + * + * - remove + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * + * - changed + * - selector: The CSS selector. This selector will have 'changed' added as a class. + * - star: If set, will add a star to this selector. It must be within the 'selector' above. + * + * - alert + * - title: The title of the alert. + * - data: The data in the alert. + * + * - css + * - selector: The CSS selector to add CSS to. + * - argument: An array of 'key': 'value' CSS selectors to set. + * + * - attr + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * - name: The name or key of the data attached to this selector. + * - value: The value of the data. + * + * - settings + * - argument: An array of settings to add to Drupal.settings via $.extend + * + * - data + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * - name: The name or key of the data attached to this selector. + * - value: The value of the data. Not just limited to strings can be any format. + * + * - redirect + * - url: The url to be redirected to. This can be an absolute URL or a Drupal path. + * + * - reload + * + * - submit + * - selector: The CSS selector to identify the form for submission. This can + * be any selector jquery uses in $(). + * + * Commands are usually created with a couple of helper functions, so they + * look like this: + * + * @code + * $commands = array(); + * $commands[] = ctools_ajax_command_replace('#ctools-object-1', 'some html here'); + * $commands[] = ctools_ajax_command_changed('#ctools-object-1'); + * ctools_ajax_render($commands); // this function exits. + * @endcode + */ + +/** + * Render an image as a button link. This will automatically apply an AJAX class + * to the link and add the appropriate javascript to make this happen. + * + * @param $image + * The path to an image to use that will be sent to theme('image') for rendering. + * @param $dest + * The destination of the link. + * @param $alt + * The alt text of the link. + * @param $class + * Any class to apply to the link. @todo this should be a options array. + */ +function ctools_ajax_image_button($image, $dest, $alt, $class = '') { + return ctools_ajax_text_button(theme('image', $image), $dest, $alt, $class); +} + +/** + * Render text as a link. This will automatically apply an AJAX class + * to the link and add the appropriate javascript to make this happen. + * + * Note: 'html' => true so be sure any text is vetted! Chances are these kinds of buttons will + * not use user input so this is a very minor concern. + * + * @param $image + * The path to an image to use that will be sent to theme('image') for rendering. + * @param $dest + * The destination of the link. + * @param $alt + * The alt text of the link. + * @param $class + * Any class to apply to the link. @todo this should be a options array. + * @param $type + * A type to use, in case a different behavior should be attached. Defaults + * to ctools-use-ajax. + */ +function ctools_ajax_text_button($text, $dest, $alt, $class = '', $type = 'ctools-use-ajax') { + return l($text, $dest, array('html' => TRUE, 'attributes' => array('class' => "$type $class", 'title' => $alt))); +} + +/** + * Create a command array for the error case. + */ +function ctools_ajax_command_error($error = '') { + return array( + 'command' => 'alert', + 'title' => t('Error'), + 'text' => $error ? $error : t('Server reports invalid input error.'), + ); +} + +/** + * Create a replace command for the AJAX responder. + * + * The replace command will replace a portion of the current document + * with the specified HTML. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $html + * The data to use with the jquery replace() function. + */ +function ctools_ajax_command_replace($selector, $html) { + return array( + 'command' => 'replace', + 'selector' => $selector, + 'data' => $html, + ); +} + +/** + * Set the HTML of a given selector to the given data. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $html + * The data to use with the jquery replace() function. + */ +function ctools_ajax_command_html($selector, $html) { + return array( + 'command' => 'html', + 'selector' => $selector, + 'data' => $html, + ); +} + +/** + * Create a prepend command for the AJAX responder. + * + * This will prepend the HTML to the specified selector. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $html + * The data to use with the jquery prepend() function. + */ +function ctools_ajax_command_prepend($selector, $html) { + return array( + 'command' => 'prepend', + 'selector' => $selector, + 'data' => $html, + ); +} + +/** + * Create an append command for the AJAX responder. + * + * This will append the HTML to the specified selector. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $html + * The data to use with the jquery append() function. + */ +function ctools_ajax_command_append($selector, $html) { + return array( + 'command' => 'append', + 'selector' => $selector, + 'data' => $html, + ); +} + +/** + * Create an after command for the AJAX responder. + * + * This will add the HTML after the specified selector. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $html + * The data to use with the jquery after() function. + */ +function ctools_ajax_command_after($selector, $html) { + return array( + 'command' => 'after', + 'selector' => $selector, + 'data' => $html, + ); +} + +/** + * Create a before command for the AJAX responder. + * + * This will add the HTML before the specified selector. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $html + * The data to use with the jquery before() function. + */ +function ctools_ajax_command_before($selector, $html) { + return array( + 'command' => 'before', + 'selector' => $selector, + 'data' => $html, + ); +} + +/** + * Create a remove command for the AJAX responder. + * + * This will remove the specified selector and everything within it. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + */ +function ctools_ajax_command_remove($selector) { + return array( + 'command' => 'remove', + 'selector' => $selector, + ); +} + +/** + * Create a changed command for the AJAX responder. + * + * This will mark an item as 'changed'. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $star + * An optional CSS selector which must be inside $selector. If specified, + * a star will be appended. + */ +function ctools_ajax_command_changed($selector, $star = '') { + return array( + 'command' => 'changed', + 'selector' => $selector, + 'star' => $star, + ); +} + +/** + * Create a css command for the AJAX responder. + * + * This will directly add CSS to the page. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $argument + * An array of key: value pairs to set in the CSS for the selector. + */ +function ctools_ajax_command_css($selector, $argument) { + return array( + 'command' => 'css', + 'selector' => $selector, + 'argument' => $argument, + ); +} + +/** + * Create a settings command for the AJAX responder. + * + * This will add CSS files to the output. Files that have already + * been processed will not be processed again. + * + * @param $argument + * An array of CSS files. + */ +function ctools_ajax_command_css_files($argument) { + return array( + 'command' => 'css_files', + 'argument' => $argument, + ); +} + +/** + * Create a settings command for the AJAX responder. + * + * This will extend Drupal.settings with the given array. + * + * @param $argument + * An array of key: value pairs to add to the settings. + */ +function ctools_ajax_command_settings($argument) { + return array( + 'command' => 'settings', + 'argument' => $argument, + ); +} + +/** + * Create a settings command for the AJAX responder. + * + * This will add javascript files to the output. Files that have already + * been processed will not be processed again. + * + * @param $argument + * An array of javascript files. + */ +function ctools_ajax_command_scripts($argument) { + return array( + 'command' => 'scripts', + 'argument' => $argument, + ); +} + +/** + * Create a data command for the AJAX responder. + * + * This will attach the name=value pair of data to the selector via + * jquery's data cache. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $name + * The name or key: of the data attached to this selector. + * @param $value + * The value of the data. Not just limited to strings can be any format. + */ +function ctools_ajax_command_data($selector, $name, $value) { + return array( + 'command' => 'data', + 'selector' => $selector, + 'name' => $name, + 'value' => $value, + ); +} + + /** + * Set a single property to a value, on all matched elements. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $name + * The name or key: of the data attached to this selector. + * @param $value + * The value of the data. + */ + function ctools_ajax_command_attr($selector, $name, $value) { + return array( + 'command' => 'attr', + 'selector' => $selector, + 'name' => $name, + 'value' => $value, + ); + } + +/** + * Force a table to be restriped. + * + * This is usually used after a table has been modified by a replace or append + * command. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + */ +function ctools_ajax_command_restripe($selector) { + return array( + 'command' => 'restripe', + 'selector' => $selector, + ); +} + +/** + * Force a client-side redirect. + * + * @param $url + * The url to be redirected to. This can be an absolute URL or a + * Drupal path. + * @param $delay + * A delay before applying the redirection, in milliseconds. + * @param $options + * An array of options to pass to the url() function. + * @param $new_window + * A bool to determine if the URL should open in a new window. + */ +function ctools_ajax_command_redirect($url, $delay = 0, $options = array(), $new_window = FALSE) { + return array( + 'command' => 'redirect', + 'url' => url($url, $options), + 'delay' => $delay, + 'new_window' => $new_window, + ); +} + +/** + * Force a reload of the current page. + */ +function ctools_ajax_command_reload() { + return array( + 'command' => 'reload', + ); +} + +/** + * Submit a form. + * + * This is useful for submitting a parent form after a child form has finished + * processing in a modal overlay. + * + * @param $selector + * The CSS selector to identify the form for submission. This can be any + * selector jquery uses in $(). + */ +function ctools_ajax_command_submit($selector) { + return array( + 'command' => 'submit', + 'selector' => $selector, + ); +} + +/** + * Render a commands array into JSON and immediately hand this back + * to the AJAX requester. + */ +function ctools_ajax_render($commands = array()) { + // Although ajax_deliver() does this, some contributed and custom modules + // render AJAX responses without using that delivery callback. + ctools_ajax_set_verification_header(); + + $js_files = array(); + $settings = ctools_process_js_files($js_files, 'header'); + $settings += ctools_process_js_files($js_files, 'footer'); + + $query_string = '?'. substr(variable_get('css_js_query_string', '0'), 0, 1); + $css = drupal_add_css(); + foreach ($css as $media => $types) { + // If CSS preprocessing is off, we still need to output the styles. + // Additionally, go through any remaining styles if CSS preprocessing is on and output the non-cached ones. + foreach ($types as $type => $files) { + if ($type == 'module') { + // Setup theme overrides for module styles. + $theme_styles = array(); + foreach (array_keys($css[$media]['theme']) as $theme_style) { + $theme_styles[] = basename($theme_style); + } + } + // The theme stuff should already be added and because of admin themes, + // this could cause different CSS to be added. + if ($type != 'theme') { + foreach ($types[$type] as $file => $preprocess) { + // If the theme supplies its own style using the name of the module style, skip its inclusion. + // This includes any RTL styles associated with its main LTR counterpart. + if ($type == 'module' && in_array(str_replace('-rtl.css', '.css', basename($file)), $theme_styles)) { + // Unset the file to prevent its inclusion when CSS aggregation is enabled. + unset($types[$type][$file]); + continue; + } + // Only include the stylesheet if it exists. + if (file_exists($file)) { + $css_files[] = array( + 'file' => base_path() . $file . $query_string, + 'media' => $media, + ); + } + } + } + } + } + + if (!empty($js_files)) { + array_unshift($commands, ctools_ajax_command_scripts(array_keys($js_files))); + } + + if (!empty($css_files)) { + array_unshift($commands, ctools_ajax_command_css_files($css_files)); + } + + if (!empty($settings)) { + array_unshift($commands, ctools_ajax_command_settings(call_user_func_array('array_merge_recursive', $settings))); + } + + if (!empty($_REQUEST['ctools_multipart'])) { + // We don't use drupal_json here because the header is not true. We're not really + // returning JSON, strictly-speaking, but rather JSON content wrapped in a <textarea> + // as per the "file uploads" example here: http://malsup.com/jquery/form/#code-samples + echo '<textarea>' . drupal_to_js($commands) . '</textarea>'; + } + else { + drupal_json($commands); + } + exit; +} + +/** + * Sets a response header for ajax.js to trust the response body. + * + * It is not safe to invoke JS commands within user-uploaded files, so this + * header protects against those being invoked. + * + * @see Drupal.ajax.ajax.options.success() + */ +function ctools_ajax_set_verification_header() { + $set = &ctools_static(__FUNCTION__); + + if (!isset($set)) { + // User-uploaded files cannot set any response headers, so the token value + // does not need to be hard to guess. + drupal_set_header('X-Drupal-Ajax-Token: 1'); + $set = TRUE; + } +} + +/** + * Send an error response back via AJAX and immediately exit. + */ +function ctools_ajax_render_error($error = '') { + $commands = array(); + $commands[] = ctools_ajax_command_error($error); + ctools_ajax_render($commands); +} + +/** + * Associate a URL to a form element with a hidden form. + * + * This is a helper function to easily associate a URL with a form element + * which can be used for different ajax functionality. + * + * You would call this function on a form element in the form function like this: + * + * @code + * $form['example'] = array( + * '#title' => t('Example'), + * '#type' => 'select', + * '#options' => array(1 => 'One', 2 => 'Two', 3 => 'Three'), + * '#default_value' => 1, + * ); + * ctools_ajax_associate_url_to_element($form, $form['example'], 'example/ajax/urlpath'); + * @endcode + * + * The AJAX request will POST the value of the form element in the + * "ctools_changed" parameter (i.e. $_POST['ctools_changed']). + * + * @param &$form + * Reference to the form element. This is required to have the #id and + * #attribute elements populated and to create the hidden form element for + * each select. + * @param &$form_element + * The form element we are going to take action on. + * @param $dest + * The URL to associate the form element to. + * @param $type + * Optional; A type to use, in case a different behavior should be attached. + * If empty the type will be set to "ctools-use-ajax" for submit elements and + * "ctools-use-ajax-onchange" for other elements. + */ +function ctools_ajax_associate_url_to_element(&$form, &$form_element, $dest, $type = '') { + drupal_add_js('misc/jquery.form.js', 'core'); + if (!isset($form_element['#id'])) { + //Create a unique ID to associate $form_element and hidden elements since we dont have an ID + $form_element['#id'] = uniqid('ctools-ajax-url-'); + + if (empty($type)) { + $type = $form_element['#type'] == 'submit' ? 'ctools-use-ajax' : 'ctools-use-ajax-onchange'; + } + + if (empty($form_element['#attributes']['class'])) { + $form_element['#attributes']['class'] = $type; + } + else { + $form_element['#attributes']['class'] .= " $type"; + } + } + + //Add hidden form element to hold base URL + $form[$form_element['#id'] . '-url'] = array( + '#type' => 'hidden', + '#value' => $dest, + '#attributes' => array('class' => $form_element['#id'] . '-url'), + ); +} + +/** + * Function that controls if ctools_ajax_page_preprocess() will run. + * + * Useful if not using Drupal's core CSS/JS handling & you wish to override it. + * If skipping the page_preprocess function you must provide the scripts and css + * files loaded on this page as a JS setting in the footer under CToolsAJAX. + * + * @param $value + * Bool; set to FALSE to disable ctools_ajax_page_preprocess() from running. + */ +function ctools_ajax_run_page_preprocess($value = TRUE) { + $run_hook = &ctools_static('ctools_ajax_page_preprocess', TRUE); + $run_hook = $value; +} + +/** + * Implement hook_preprocess_page. Process variables for page.tpl.php + * + * @param $variables + * The existing theme data structure. + */ +function ctools_ajax_page_preprocess(&$variables) { + // See if we will be running this hook. + $run_hook = &ctools_static(__FUNCTION__, TRUE); + if (!$run_hook) { + return; + } + + $js_files = $css_files = array(); + ctools_process_js_files($js_files, 'header'); + ctools_process_js_files($js_files, 'footer'); + ctools_process_css_files($css_files, $variables['css']); + + // Add loaded JS and CSS information to the footer, so that an AJAX + // request knows if they are already loaded. + // For inline Javascript to validate as XHTML, all Javascript containing + // XHTML needs to be wrapped in CDATA. To make that backwards compatible + // with HTML 4, we need to comment out the CDATA-tag. + $loaded = array('CToolsAJAX' => array('scripts' => $js_files, 'css' => $css_files)); + $embed_prefix = "\n<!--//--><![CDATA[//><!--\n"; + $embed_suffix = "\n//--><!]]>\n"; + $variables['closure'].= '<script type="text/javascript">' . $embed_prefix . 'jQuery.extend(Drupal.settings, ' . drupal_to_js($loaded) . ");" . $embed_suffix . "</script>\n"; +} + +/** + * Create a list of javascript files that are on the page. + * + * @param $js_files + * Array of js files that are loaded on this page. + * @param $scope + * String usually containing header or footer. + * @param $scripts + * (Optional) array returned from drupal_add_js(). If NULL then it will load + * the array from drupal_add_js for the given scope. + * @return array $settings + * The JS 'setting' array for the given scope. + */ +function ctools_process_js_files(&$js_files, $scope, $scripts = NULL) { + // Automatically extract any 'settings' added via drupal_add_js() and make + // them the first command. + if (empty($scripts)) { + $scripts = drupal_add_js(NULL, NULL, $scope); + } + + // Get replacements that are going to be made by contrib modules and take + // them into account so we don't double-load scripts. + static $replacements = NULL; + if (!isset($replacements)) { + $replacements = module_invoke_all('js_replacements'); + } + + $settings = array(); + foreach ($scripts as $type => $data) { + switch ($type) { + case 'setting': + $settings = $data; + break; + case 'inline': + case 'theme': + // Presently we ignore inline javascript. + // Theme JS is already added and because of admin themes, this could add + // improper JS to the page. + break; + default: + // If JS preprocessing is off, we still need to output the scripts. + // Additionally, go through any remaining scripts if JS preprocessing is on and output the non-cached ones. + foreach ($data as $path => $info) { + // If the script is being replaced, take that replacement into account. + $final_path = isset($replacements[$type][$path]) ? $replacements[$type][$path] : $path; + $js_files[base_path() . $final_path] = TRUE; + } + } + } + + return $settings; +} + +/** + * Create a list of CSS files to add to the page. + * + * @param $css_files + * Array of css files that are loaded on this page. Passed by reference and + * previous values are wiped. + * @param $css + * Array returned from drupal_add_css() or $variables['css'] from + * hook_preprocess_page. + */ +function ctools_process_css_files(&$css_files, $css) { + // Go through all CSS files that are being added to the page and catalog them. + $css_files = array(); + foreach ($css as $media => $types) { + // If CSS preprocessing is off, we still need to output the styles. + // Additionally, go through any remaining styles if CSS preprocessing is on and output the non-cached ones. + foreach ($types as $type => $files) { + if ($type == 'module') { + // Setup theme overrides for module styles. + $theme_styles = array(); + foreach (array_keys($css[$media]['theme']) as $theme_style) { + $theme_styles[] = basename($theme_style); + } + } + foreach ($types[$type] as $file => $preprocess) { + // If the theme supplies its own style using the name of the module style, skip its inclusion. + // This includes any RTL styles associated with its main LTR counterpart. + if ($type == 'module' && in_array(str_replace('-rtl.css', '.css', basename($file)), $theme_styles)) { + // Unset the file to prevent its inclusion when CSS aggregation is enabled. + unset($types[$type][$file]); + continue; + } + // Only include the stylesheet if it exists. + if (file_exists($file)) { + $css_files[base_path() . $file] = TRUE; + } + } + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/cleanstring.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/cleanstring.inc new file mode 100644 index 0000000000000000000000000000000000000000..027def151da8acfd02edf6c0986b4dfe544aaaf6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/cleanstring.inc @@ -0,0 +1,205 @@ +<?php +// $Id $ + +/** + * @file + * Helper class to clean strings to make them URL safe and translatable. + * + * This was copied directly from pathauto and put here to be made available + * to all, because more things than just pathauto want URL safe strings. + * + * To use, simply: + * @code + * ctools_include('cleanstring'); + * $output = ctools_cleanstring($string); + * + * You can add a variety of settings as an array in the second argument, + * including words to ignore, how to deal with punctuation, length + * limits, and more. See the function itself for options. + */ + +/** + * Matches Unicode character classes. + * + * See: http://www.unicode.org/Public/UNIDATA/UCD.html#General_Category_Values + * + * The index only contains the following character classes: + * Lu Letter, Uppercase + * Ll Letter, Lowercase + * Lt Letter, Titlecase + * Lo Letter, Other + * Nd Number, Decimal Digit + * No Number, Other + * + * Copied from search.module's PREG_CLASS_SEARCH_EXCLUDE. + */ +define('CTOOLS_PREG_CLASS_ALNUM', +'\x{0}-\x{2f}\x{3a}-\x{40}\x{5b}-\x{60}\x{7b}-\x{bf}\x{d7}\x{f7}\x{2b0}-'. +'\x{385}\x{387}\x{3f6}\x{482}-\x{489}\x{559}-\x{55f}\x{589}-\x{5c7}\x{5f3}-'. +'\x{61f}\x{640}\x{64b}-\x{65e}\x{66a}-\x{66d}\x{670}\x{6d4}\x{6d6}-\x{6ed}'. +'\x{6fd}\x{6fe}\x{700}-\x{70f}\x{711}\x{730}-\x{74a}\x{7a6}-\x{7b0}\x{901}-'. +'\x{903}\x{93c}\x{93e}-\x{94d}\x{951}-\x{954}\x{962}-\x{965}\x{970}\x{981}-'. +'\x{983}\x{9bc}\x{9be}-\x{9cd}\x{9d7}\x{9e2}\x{9e3}\x{9f2}-\x{a03}\x{a3c}-'. +'\x{a4d}\x{a70}\x{a71}\x{a81}-\x{a83}\x{abc}\x{abe}-\x{acd}\x{ae2}\x{ae3}'. +'\x{af1}-\x{b03}\x{b3c}\x{b3e}-\x{b57}\x{b70}\x{b82}\x{bbe}-\x{bd7}\x{bf0}-'. +'\x{c03}\x{c3e}-\x{c56}\x{c82}\x{c83}\x{cbc}\x{cbe}-\x{cd6}\x{d02}\x{d03}'. +'\x{d3e}-\x{d57}\x{d82}\x{d83}\x{dca}-\x{df4}\x{e31}\x{e34}-\x{e3f}\x{e46}-'. +'\x{e4f}\x{e5a}\x{e5b}\x{eb1}\x{eb4}-\x{ebc}\x{ec6}-\x{ecd}\x{f01}-\x{f1f}'. +'\x{f2a}-\x{f3f}\x{f71}-\x{f87}\x{f90}-\x{fd1}\x{102c}-\x{1039}\x{104a}-'. +'\x{104f}\x{1056}-\x{1059}\x{10fb}\x{10fc}\x{135f}-\x{137c}\x{1390}-\x{1399}'. +'\x{166d}\x{166e}\x{1680}\x{169b}\x{169c}\x{16eb}-\x{16f0}\x{1712}-\x{1714}'. +'\x{1732}-\x{1736}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17db}\x{17dd}'. +'\x{17f0}-\x{180e}\x{1843}\x{18a9}\x{1920}-\x{1945}\x{19b0}-\x{19c0}\x{19c8}'. +'\x{19c9}\x{19de}-\x{19ff}\x{1a17}-\x{1a1f}\x{1d2c}-\x{1d61}\x{1d78}\x{1d9b}-'. +'\x{1dc3}\x{1fbd}\x{1fbf}-\x{1fc1}\x{1fcd}-\x{1fcf}\x{1fdd}-\x{1fdf}\x{1fed}-'. +'\x{1fef}\x{1ffd}-\x{2070}\x{2074}-\x{207e}\x{2080}-\x{2101}\x{2103}-\x{2106}'. +'\x{2108}\x{2109}\x{2114}\x{2116}-\x{2118}\x{211e}-\x{2123}\x{2125}\x{2127}'. +'\x{2129}\x{212e}\x{2132}\x{213a}\x{213b}\x{2140}-\x{2144}\x{214a}-\x{2b13}'. +'\x{2ce5}-\x{2cff}\x{2d6f}\x{2e00}-\x{3005}\x{3007}-\x{303b}\x{303d}-\x{303f}'. +'\x{3099}-\x{309e}\x{30a0}\x{30fb}-\x{30fe}\x{3190}-\x{319f}\x{31c0}-\x{31cf}'. +'\x{3200}-\x{33ff}\x{4dc0}-\x{4dff}\x{a015}\x{a490}-\x{a716}\x{a802}\x{a806}'. +'\x{a80b}\x{a823}-\x{a82b}\x{e000}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}\x{fd3f}'. +'\x{fdfc}-\x{fe6b}\x{feff}-\x{ff0f}\x{ff1a}-\x{ff20}\x{ff3b}-\x{ff40}\x{ff5b}-'. +'\x{ff65}\x{ff70}\x{ff9e}\x{ff9f}\x{ffe0}-\x{fffd}'); + + +/** + * Clean up a string value provided by a module. + * + * Resulting string contains only alphanumerics and separators. + * + * @param $string + * A string to clean. + * @param $settings + * An optional array of settings to use. + * - 'clean slash': If set, slashes will be cleaned. Defaults to TRUE, + * so you have to explicitly set this to FALSE to not clean the + * slashes. + * - 'ignore words': Set to an array of words that will be removed + * rather than made safe. Defaults to an empty array. + * - 'separator': Change spaces and untranslatable characters to + * this character. Defaults to '-'. + * - 'replacements': An array of direct replacements to be made that will + * be implemented via strtr(). Defaults to an empty array. + * - 'transliterate': If set, use the transliteration replacements. If set + * to an array, use these replacements instead of the defaults in CTools. + * Defaults to FALSE. + * - 'reduce ascii': If set to TRUE further reduce to ASCII96 only. Defaults + * to TRUE. + * - 'max length': If set to a number, reduce the resulting string to this + * maximum length. Defaults to no maximum length. + * - 'lower case': If set to TRUE, convert the result to lower case. + * Defaults to false. + * These settings will be passed through drupal_alter. + * + * @return + * The cleaned string. + */ +function ctools_cleanstring($string, $settings = array()) { + $settings += array( + 'clean slash' => TRUE, + 'ignore words' => array(), + 'separator' => '-', + 'replacements' => array(), + 'transliterate' => FALSE, + 'reduce ascii' => TRUE, + 'max length' => FALSE, + 'lower case' => FALSE, + ); + + // Allow modules to make other changes to the settings. + if (isset($settings['clean id'])) { + drupal_alter('ctools_cleanstring_' . $settings['clean id'], $settings); + } + + drupal_alter('ctools_cleanstring', $settings); + + $output = $string; + + // Do any replacements the user selected up front. + if (!empty($settings['replacements'])) { + $output = strtr($output, $settings['replacements']); + } + + // Remove slashes if instructed to do so. + if ($settings['clean slash']) { + $output = str_replace('/', '', $output); + } + + if (!empty($settings['transliterate']) && module_exists('transliteration')) { + $output = transliteration_get($output); + } + + // Reduce to the subset of ASCII96 letters and numbers + if ($settings['reduce ascii']) { + $pattern = '/[^a-zA-Z0-9\/]+/'; + $output = preg_replace($pattern, $settings['separator'], $output); + } + + // Get rid of words that are on the ignore list + if (!empty($settings['ignore words'])) { + $ignore_re = '\b'. preg_replace('/,/', '\b|\b', $settings['ignore words']) .'\b'; + + if (function_exists('mb_eregi_replace')) { + $output = mb_eregi_replace($ignore_re, '', $output); + } + else { + $output = preg_replace("/$ignore_re/i", '', $output); + } + } + + // Always replace whitespace with the separator. + $output = preg_replace('/\s+/', $settings['separator'], $output); + + // In preparation for pattern matching, + // escape the separator if and only if it is not alphanumeric. + if (isset($settings['separator'])) { + if (preg_match('/^[^'. CTOOLS_PREG_CLASS_ALNUM .']+$/uD', $settings['separator'])) { + $seppattern = $settings['separator']; + } + else { + $seppattern = '\\'. $settings['separator']; + } + // Trim any leading or trailing separators (note the need to + $output = preg_replace("/^$seppattern+|$seppattern+$/", '', $output); + + // Replace multiple separators with a single one + $output = preg_replace("/$seppattern+/", $settings['separator'], $output); + } + + // Enforce the maximum component length + if (!empty($settings['max length'])) { + $output = ctools_cleanstring_truncate($output, $settings['max length'], $settings['separator']); + } + + if (!empty($settings['lower case'])) { + $output = drupal_strtolower($output); + } + return $output; +} + +/** + * A friendly version of truncate_utf8. + * + * @param $string + * The string to be truncated. + * @param $length + * An integer for the maximum desired length. + * @param $separator + * A string which contains the word boundary such as - or _. + * + * @return + * The string truncated below the maxlength. + */ +function ctools_cleanstring_truncate($string, $length, $separator) { + if (drupal_strlen($string) > $length) { + $string = drupal_substr($string, 0, $length + 1); // leave one more character + if ($last_break = strrpos($string, $separator)) { // space exists AND is not on position 0 + $string = substr($string, 0, $last_break); + } + else { + $string = drupal_substr($string, 0, $length); + } + } + return $string; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/collapsible.theme.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/collapsible.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..7d6d6af664a83802bdb29515ad2208624fbbfa20 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/collapsible.theme.inc @@ -0,0 +1,75 @@ +<?php + +/** + * @file + * Theme function for the collapsible div tool. + * + * Call theme('ctools_collapsible', $handle, $content, $collapsed) to draw the + * div. The theme function is not necessary; you can add the classes, js and css + * yourself if you really want to. + */ + +/** + * Delegated implementation of hook_theme() + */ +function ctools_collapsible_theme(&$items) { + $items['ctools_collapsible'] = array( + 'arguments' => array('handle' => NULL, 'content' => NULL, 'collapsed' => FALSE), + 'file' => 'includes/collapsible.theme.inc', + ); + $items['ctools_collapsible_remembered'] = array( + 'arguments' => array('id' => NULL, 'handle' => NULL, 'content' => NULL, 'collapsed' => FALSE), + 'file' => 'includes/collapsible.theme.inc', + ); +} + +/** + * Render a collapsible div. + * + * @param $handle + * Text to put in the handle/title area of the div. + * @param $content + * Text to put in the content area of the div, this is what will get + * collapsed + * @param $collapsed = FALSE + * If true, this div will start out collapsed. + */ +function theme_ctools_collapsible($handle, $content, $collapsed = FALSE) { + ctools_add_js('collapsible-div'); + ctools_add_css('collapsible-div'); + + $class = $collapsed ? ' ctools-collapsed' : ''; + $output = '<div class="ctools-collapsible-container' . $class . '">'; + $output .= '<div class="ctools-collapsible-handle">' . $handle . '</div>'; + $output .= '<div class="ctools-collapsible-content">' . $content . '</div>'; + $output .= '</div>'; + + return $output; +} + +/** + * Render a collapsible div whose state will be remembered. + * + * @param $id + * The CSS id of the container. This is required. + * @param $handle + * Text to put in the handle/title area of the div. + * @param $content + * Text to put in the content area of the div, this is what will get + * collapsed + * @param $collapsed = FALSE + * If true, this div will start out collapsed. + */ +function theme_ctools_collapsible_remembered($id, $handle, $content, $collapsed = FALSE) { + ctools_add_js('collapsible-div'); + ctools_add_css('collapsible-div'); + + $class = $collapsed ? ' ctools-collapsed' : ''; + $output = '<div id="' . $id . '" class="ctools-collapsible-remember ctools-collapsible-container' . $class . '">'; + $output .= '<div class="ctools-collapsible-handle">' . $handle . '</div>'; + $output .= '<div class="ctools-collapsible-content">' . $content . '</div>'; + $output .= '</div>'; + + return $output; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.inc new file mode 100644 index 0000000000000000000000000000000000000000..e23c2a93efdb084e1685b0181767ef921367affd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.inc @@ -0,0 +1,804 @@ +<?php + +/** + * @file + * Contains the tools to handle pluggable content that can be used by other + * applications such as Panels or Dashboard. + * + * See the context-content.html file in advanced help for documentation + * of this tool. + */ + +/** + * Implementation of hook_ctools_plugin_*. + * + * Give information to CTools about the content types plugin. + */ +function ctools_ctools_plugin_content_types() { + return array( + 'cache' => FALSE, + 'process' => 'ctools_content_process', + ); +} + +/** + * Provide defaults for a content type. + * + * Currently we check for automatically named callbacks to make life a little + * easier on the developer. + */ +function ctools_content_process(&$plugin, $info) { + $function_base = $plugin['module'] . '_' . $plugin['name'] . '_content_type_'; + + if (empty($plugin['render callback']) && function_exists($function_base . 'render')) { + $plugin['render callback'] = $function_base . 'render'; + } + + if (empty($plugin['admin title'])) { + if (function_exists($function_base . 'admin_title')) { + $plugin['admin title'] = $function_base . 'admin_title'; + } + else { + $plugin['admin title'] = $plugin['title']; + } + } + + if (empty($plugin['admin info']) && function_exists($function_base . 'admin_info')) { + $plugin['admin info'] = $function_base . 'admin_info'; + } + + if (!isset($plugin['edit form']) && function_exists($function_base . 'edit_form')) { + $plugin['edit form'] = $function_base . 'edit_form'; + } + + if (!isset($plugin['add form']) && function_exists($function_base . 'add_form')) { + $plugin['add form'] = $function_base . 'add_form'; + } + + if (!isset($plugin['add form']) && function_exists($function_base . 'edit_form')) { + $plugin['add form'] = $function_base . 'edit_form'; + } + + if (!isset($plugin['description'])) { + $plugin['description'] = ''; + } + + if (!isset($plugin['icon'])) { + $plugin['icon'] = ctools_content_admin_icon($plugin); + } + + // Another ease of use check: + if (!isset($plugin['content types'])) { + // If a subtype plugin exists, try to use it. Otherwise assume single. + if (function_exists($function_base . 'content_types')) { + $plugin['content types'] = $function_base . 'content_types'; + } + else { + $type = array( + 'title' => $plugin['title'], + 'description' => $plugin['description'], + 'icon' => ctools_content_admin_icon($plugin), + 'category' => $plugin['category'], + ); + + if (isset($plugin['required context'])) { + $type['required context'] = $plugin['required context']; + } + if (isset($plugin['top level'])) { + $type['top level'] = $plugin['top level']; + } + $plugin['content types'] = array($plugin['name'] => $type); + if (!isset($plugin['single'])) { + $plugin['single'] = TRUE; + } + } + } +} + +/** + * Fetch metadata on a specific content_type plugin. + * + * @param $content type + * Name of a panel content type. + * + * @return + * An array with information about the requested panel content type. + */ +function ctools_get_content_type($content_type) { + ctools_include('context'); + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'content_types', $content_type); +} + +/** + * Fetch metadata for all content_type plugins. + * + * @return + * An array of arrays with information about all available panel content types. + */ +function ctools_get_content_types() { + ctools_include('context'); + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'content_types'); +} + +/** + * Get all of the individual subtypes provided by a given content type. This + * would be all of the blocks for the block type, or all of the views for + * the view type. + * + * @param $type + * The content type to load. + * + * @return + * An array of all subtypes available. + */ +function ctools_content_get_subtypes($type) { + static $cache = array(); + + $subtypes = array(); + + if (is_array($type)) { + $plugin = $type; + } + else { + $plugin = ctools_get_content_type($type); + } + + if (empty($plugin) || empty($plugin['name'])) { + return; + } + + if (isset($cache[$plugin['name']])) { + return $cache[$plugin['name']]; + } + + if (isset($plugin['content types'])) { + $function = $plugin['content types']; + if (is_array($function)) { + $subtypes = $function; + } + else if (function_exists($function)) { + // Cast to array to prevent errors from non-array returns. + $subtypes = (array) $function($plugin); + } + } + + // Walk through the subtypes and ensure minimal settings are + // retained. + foreach ($subtypes as $id => $subtype) { + // Use exact name since this is a modify by reference. + ctools_content_prepare_subtype($subtypes[$id], $plugin); + } + + $cache[$plugin['name']] = $subtypes; + + return $subtypes; +} + +/** + * Given a content type and a subtype id, return the information about that + * content subtype. + * + * @param $type + * The content type being fetched. + * @param $subtype_id + * The id of the subtype being fetched. + * + * @return + * An array of information describing the content subtype. + */ +function ctools_content_get_subtype($type, $subtype_id) { + $subtype = array(); + if (is_array($type)) { + $plugin = $type; + } + else { + $plugin = ctools_get_content_type($type); + } + + $function = ctools_plugin_get_function($plugin, 'content type'); + if ($function) { + $subtype = $function($subtype_id, $plugin); + } + else { + $subtypes = ctools_content_get_subtypes($type); + if (isset($subtypes[$subtype_id])) { + $subtype = $subtypes[$subtype_id]; + } + // If there's only 1 and we somehow have the wrong subtype ID, do not + // care. Return the proper subtype anyway. + if (empty($subtype) && !empty($plugin['single'])) { + $subtype = current($subtypes); + } + } + + if ($subtype) { + ctools_content_prepare_subtype($subtype, $plugin); + } + return $subtype; +} + +/** + * Ensure minimal required settings on a content subtype exist. + */ +function ctools_content_prepare_subtype(&$subtype, $plugin) { + foreach (array('path', 'js', 'css') as $key) { + if (!isset($subtype[$key]) && isset($plugin[$key])) { + $subtype[$key] = $plugin[$key]; + } + } +} + +/** + * Get the content from a given content type. + * + * @param $type + * The content type. May be the name or an already loaded content type plugin. + * @param $subtype + * The name of the subtype being rendered. + * @param $conf + * The configuration for the content type. + * @param $keywords + * An array of replacement keywords that come from outside contexts. + * @param $args + * The arguments provided to the owner of the content type. Some content may + * wish to configure itself based on the arguments the panel or dashboard + * received. + * @param $context + * An array of context objects available for use. + * @param $incoming_content + * Any incoming content, if this display is a wrapper. + * + * @return + * The content as rendered by the plugin. This content should be an array + * with the following possible keys: + * - title: The safe to render title of the content. + * - content: The safe to render HTML content. + * - links: An array of links associated with the content suitable for + * theme('links'). + * - more: An optional 'more' link (destination only) + * - admin_links: Administrative links associated with the content, suitable + * for theme('links'). + * - feeds: An array of feed icons or links associated with the content. + * Each member of the array is rendered HTML. + * - type: The content type. + * - subtype: The content subtype. These two may be used together as + * module-delta for block style rendering. + */ +function ctools_content_render($type, $subtype, $conf, $keywords = array(), $args = array(), $context = array(), $incoming_content = '') { + if (is_array($type)) { + $plugin = $type; + } + else { + $plugin = ctools_get_content_type($type); + } + + $subtype_info = ctools_content_get_subtype($plugin, $subtype); + + $function = ctools_plugin_get_function($subtype_info, 'render callback'); + if (!$function) { + $function = ctools_plugin_get_function($plugin, 'render callback'); + } + + if ($function) { + $pane_context = ctools_content_select_context($plugin, $subtype, $conf, $context); + if ($pane_context === FALSE) { + return; + } + + $content = $function($subtype, $conf, $args, $pane_context, $incoming_content); + if (empty($content)) { + return; + } + + // Set up some defaults and other massaging on the content before we hand + // it back to the caller. + if (!isset($content->type)) { + $content->type = $plugin['name']; + } + + if (!isset($content->subtype)) { + $content->subtype = $subtype; + } + + // Override the title if configured to + if (!empty($conf['override_title'])) { + // Give previous title as an available substitution here. + $keywords['%title'] = empty($content->title) ? '' : $content->title; + $content->original_title = $keywords['%title']; + $content->title = $conf['override_title_text']; + } + + if (!empty($content->title)) { + // Perform substitutions + if (!empty($keywords) || !empty($context)) { + $content->title = ctools_context_keyword_substitute($content->title, $keywords, $context); + } + + // Sterilize the title + $content->title = filter_xss_admin($content->title); + + // If a link is specified, populate. + if (!empty($content->title_link)) { + if (!is_array($content->title_link)) { + $url = array('href' => $content->title_link); + } + else { + $url = $content->title_link; + } + // set defaults so we don't bring up notices + $url += array('href' => '', 'attributes' => NULL, 'query' => NULL, 'fragment' => NULL, 'absolute' => NULL, 'html' => TRUE); + $content->title = l($content->title, $url['href'], $url); + } + } + + return $content; + } +} + +/** + * Determine if a content type can be edited or not. + * + * Some content types simply have their content and no options. This function + * lets a UI determine if it should display an edit link or not. + */ +function ctools_content_editable($type, $subtype, $conf) { + if (empty($type['edit form']) && empty($subtype['edit form'])) { + return FALSE; + } + + $function = FALSE; + if (!empty($subtype['check editable'])) { + $function = ctools_plugin_get_function($subtype, 'check editable'); + } + elseif (!empty($type['check editable'])) { + $function = ctools_plugin_get_function($type, 'check editable'); + } + + if ($function) { + return $function($type, $subtype, $conf); + } + + return TRUE; +} + +/** + * Get the administrative title from a given content type. + * + * @param $type + * The content type. May be the name or an already loaded content type object. + * @param $subtype + * The subtype being rendered. + * @param $conf + * The configuration for the content type. + * @param $context + * An array of context objects available for use. These may be placeholders. + */ +function ctools_content_admin_title($type, $subtype, $conf, $context = NULL) { + if (is_array($type)) { + $plugin = $type; + } + else if (is_string($type)) { + $plugin = ctools_get_content_type($type); + } + else { + return; + } + + if ($function = ctools_plugin_get_function($plugin, 'admin title')) { + $pane_context = ctools_content_select_context($plugin, $subtype, $conf, $context); + if ($pane_context === FALSE) { + if ($plugin['name'] == $subtype) { + return t('@type will not display due to missing context', array('@type' => $plugin['name'])); + } + return t('@type:@subtype will not display due to missing context', array('@type' => $plugin['name'], '@subtype' => $subtype)); + } + + return $function($subtype, $conf, $pane_context); + } + else if (isset($plugin['admin title'])) { + return $plugin['admin title']; + } + else if (isset($plugin['title'])) { + return $plugin['title']; + } +} + +/** + * Get the proper icon path to use, falling back to default icons if no icon exists. + * + * $subtype + * The loaded subtype info. + */ +function ctools_content_admin_icon($subtype) { + $icon = ''; + + if (isset($subtype['icon'])) { + $icon = $subtype['icon']; + if (!file_exists($icon)) { + $icon = $subtype['path'] . '/' . $icon; + } + } + + if (empty($icon) || !file_exists($icon)) { + $icon = ctools_image_path('no-icon.png'); + } + + return $icon; +} + +/** + * Set up the default $conf for a new instance of a content type. + */ +function ctools_content_get_defaults($plugin, $subtype) { + if (isset($plugin['defaults'])) { + $defaults = $plugin['defaults']; + } + else if (isset($subtype['defaults'])) { + $defaults = $subtype['defaults']; + } + if (isset($defaults)) { + if (is_string($defaults) && function_exists($defaults)) { + if ($return = $defaults($pane)) { + return $return; + } + } + else if (is_array($defaults)) { + return $defaults; + } + } + + return array(); +} + +/** + * Get the administrative title from a given content type. + * + * @param $type + * The content type. May be the name or an already loaded content type object. + * @param $subtype + * The subtype being rendered. + * @param $conf + * The configuration for the content type. + * @param $context + * An array of context objects available for use. These may be placeholders. + */ +function ctools_content_admin_info($type, $subtype, $conf, $context = NULL) { + if (is_array($type)) { + $plugin = $type; + } + else { + $plugin = ctools_get_content_type($type); + } + + if ($function = ctools_plugin_get_function($plugin, 'admin info')) { + $output = $function($subtype, $conf, $context); + } + if (empty($output) || !is_object($output)) { + $output = new stdClass(); + $output->title = t('No info'); + $output->content =t ('No info available.'); + } + return $output; +} + +/** + * Add the default FAPI elements to the content type configuration form + */ +function ctools_content_configure_form_defaults(&$form, &$form_state) { + $plugin = $form_state['plugin']; + $subtype = $form_state['subtype']; + $contexts = isset($form_state['contexts']) ? $form_state['contexts'] : NULL; + $conf = $form_state['conf']; + + $add_submit = FALSE; + if (!empty($subtype['required context']) && is_array($contexts)) { + $form['context'] = ctools_context_selector($contexts, $subtype['required context'], isset($conf['context']) ? $conf['context'] : array()); + $add_submit = TRUE; + } + + ctools_include('dependent'); + + // Unless we're not allowed to override the title on this content type, add this + // gadget to all panes. + if (empty($plugin['no title override']) && empty($subtype['no title override'])) { + $form['aligner_start'] = array( + '#value' => '<div class="option-text-aligner">', + ); + $form['override_title'] = array( + '#type' => 'checkbox', + '#default_value' => isset($conf['override_title']) ? $conf['override_title'] : '', + '#title' => t('Override title'), + '#id' => 'override-title-checkbox', + ); + $form['override_title_text'] = array( + '#type' => 'textfield', + '#default_value' => isset($conf['override_title_text']) ? $conf['override_title_text'] : '', + '#size' => 35, + '#id' => 'override-title-textfield', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('override-title-checkbox' => array(1)), + '#dependency_type' => 'disable', + ); + $form['aligner_stop'] = array( + '#value' => '</div><div style="clear: both; padding: 0; margin: 0"></div>', + ); + if (is_array($contexts)) { + $form['override_title_markup'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => t('You may use %keywords from contexts, as well as %title to contain the original title.'), + ); + } + $add_submit = TRUE; + } + + if ($add_submit) { + // '#submit' is already set up due to the wizard. + $form['#submit'][] = 'ctools_content_configure_form_defaults_submit'; + } + return $form; +} + +/** + * Submit handler to store context/title override info. + */ +function ctools_content_configure_form_defaults_submit(&$form, &$form_state) { + if (isset($form_state['values']['context'])) { + $form_state['conf']['context'] = $form_state['values']['context']; + } + if (isset($form_state['values']['override_title'])) { + $form_state['conf']['override_title'] = $form_state['values']['override_title']; + $form_state['conf']['override_title_text'] = $form_state['values']['override_title_text']; + } +} + +/** + * Get the config form. + * + * The $form_info and $form_state need to be preconfigured with data you'll need + * such as whether or not you're using ajax, or the modal. $form_info will need + * your next/submit callbacks so that you can cache your data appropriately. + * + * @return + * If this function returns false, no form exists. + */ +function ctools_content_form($op, $form_info, &$form_state, $plugin, $subtype_name, $subtype, &$conf, $step = NULL) { + $form_state += array( + 'plugin' => $plugin, + 'subtype' => $subtype, + 'subtype_name' => $subtype_name, + 'conf' => &$conf, + 'op' => $op, + ); + + $form_info += array( + 'id' => 'ctools_content_form', + 'show back' => TRUE, + ); + + // Turn the forms defined in the plugin into the format the wizard needs. + if ($op == 'add') { + if (!empty($subtype['add form'])) { + _ctools_content_create_form_info($form_info, $subtype['add form'], $subtype, $subtype, $op); + } + else if (!empty($plugin['add form'])) { + _ctools_content_create_form_info($form_info, $plugin['add form'], $plugin, $subtype, $op); + } + } + + if (empty($form_info['order'])) { + // Use the edit form for the add form if add form was completely left off. + if (!empty($subtype['edit form'])) { + _ctools_content_create_form_info($form_info, $subtype['edit form'], $subtype, $subtype, $op); + } + else if (!empty($plugin['edit form'])) { + _ctools_content_create_form_info($form_info, $plugin['edit form'], $plugin, $subtype, $op); + } + } + + if (empty($form_info['order'])) { + return FALSE; + } + + ctools_include('wizard'); + return ctools_wizard_multistep_form($form_info, $step, $form_state); + +} + +function _ctools_content_create_form_info(&$form_info, $info, $plugin, $subtype, $op) { + if (is_string($info)) { + if (empty($subtype['title'])) { + $title = t('Configure'); + } + else if ($op == 'add') { + $title = t('Configure new !subtype_title', array('!subtype_title' => $subtype['title'])); + } + else { + $title = t('Configure !subtype_title', array('!subtype_title' => $subtype['title'])); + } + $form_info['order'] = array('form' => $title); + $form_info['forms'] = array( + 'form' => array( + 'title' => $title, + 'form id' => $info, + 'wrapper' => 'ctools_content_configure_form_defaults', + ), + ); + } + else if (is_array($info)) { + $form_info['order'] = array(); + $form_info['forms'] = array(); + $count = 0; + $base = 'step'; + $wrapper = NULL; + foreach ($info as $form_id => $title) { + // @todo -- docs say %title can be used to sub for the admin title. + $step = $base . ++$count; + if (empty($wrapper)) { + $wrapper = $step; + } + + if (is_array($title)) { + if (!empty($title['default'])) { + $wrapper = $step; + } + $title = $title['title']; + } + + $form_info['order'][$step] = $title; + $form_info['forms'][$step] = array( + 'title' => $title, + 'form id' => $form_id, + ); + } + if ($wrapper) { + $form_info['forms'][$wrapper]['wrapper'] = 'ctools_content_configure_form_defaults'; + } + } +} + +/** + * Get an array of all available content types that can be fed into the + * display editor for the add content list. + * + * @param $context + * If a context is provided, content that requires that context can apepar. + * @param $has_content + * Whether or not the display will have incoming content + * @param $allowed_types + * An array of allowed content types (pane types) keyed by content_type . '-' . sub_type + * @param $default_types + * A default allowed/denied status for content that isn't known about + */ +function ctools_content_get_available_types($contexts = NULL, $has_content = FALSE, $allowed_types = NULL, $default_types = NULL) { + $plugins = ctools_get_content_types(); + $available = array(); + + foreach ($plugins as $id => $plugin) { + foreach (ctools_content_get_subtypes($plugin) as $subtype_id => $subtype) { + // exclude items that require content if we're saying we don't + // provide it. + if (!empty($subtype['requires content']) && !$has_content) { + continue; + } + + // Check to see if the content type can be used in this context. + if (!empty($subtype['required context'])) { + if (!ctools_context_match_requirements($contexts, $subtype['required context'])) { + continue; + } + } + + // Check to see if the passed-in allowed types allows this content. + if ($allowed_types) { + $key = $id . '-' . $subtype_id; + if (!isset($allowed_types[$key])) { + $allowed_types[$key] = isset($default_types[$id]) ? $default_types[$id] : $default_types['other']; + } + if (!$allowed_types[$key]) { + continue; + } + } + + // If we made it through all the tests, then we can use this content. + $available[$id][$subtype_id] = $subtype; + } + } + return $available; +} + +/** + * Get an array of all content types that can be fed into the + * display editor for the add content list, regardless of + * availability. + * + */ +function ctools_content_get_all_types() { + $plugins = ctools_get_content_types(); + $available = array(); + + foreach ($plugins as $id => $plugin) { + foreach (ctools_content_get_subtypes($plugin) as $subtype_id => $subtype) { + // If we made it through all the tests, then we can use this content. + $available[$id][$subtype_id] = $subtype; + } + } + return $available; +} + +/** + * Select the context to be used for a piece of content, based upon config. + * + * @param $plugin + * The content plugin + * @param $subtype + * The subtype of the content. + * @param $conf + * The configuration array that should contain the context. + * @param $contexts + * A keyed array of available contexts. + * + * @return + * The matching contexts or NULL if none or necessary, or FALSE if + * requirements can't be met. + */ +function ctools_content_select_context($plugin, $subtype, $conf, $contexts) { + // Identify which of our possible contexts apply. + if (empty($subtype)) { + return; + } + + $subtype_info = ctools_content_get_subtype($plugin, $subtype); + if (empty($subtype_info)) { + return; + } + + if (!empty($subtype_info['all contexts']) || !empty($plugin['all contexts'])) { + return $contexts; + } + + // If the content requires a context, fetch it; if no context is returned, + // do not display the pane. + if (empty($subtype_info['required context'])) { + return; + } + + // Deal with dynamic required contexts not getting updated in the panes. + // For example, Views let you dynamically change context info. While + // we cannot be perfect, one thing we can do is if no context at all + // was asked for, and then was later added but none is selected, make + // a best guess as to what context should be used. THis is right more + // than it's wrong. + if (is_array($subtype_info['required context'])) { + if (empty($conf['context']) || count($subtype_info['required context']) != count($conf['context'])) { + foreach($subtype_info['required context'] as $index => $required) { + if (!isset($conf['context'][$index])) { + $filtered = ctools_context_filter($contexts, $required); + if ($filtered) { + $keys = array_keys($filtered); + $conf['context'][$index] = array_shift($keys); + } + } + } + } + } + else { + if (empty($conf['context'])) { + $filtered = ctools_context_filter($contexts, $subtype_info['required context']); + if ($filtered) { + $keys = array_keys($filtered); + $conf['context'] = array_shift($keys); + } + } + } + + if (empty($conf['context'])) { + return; + } + + $context = ctools_context_select($contexts, $subtype_info['required context'], $conf['context']); + + return $context; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.menu.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..07e00cc6b49912c10ca215b4cd91379ce8c2daa3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.menu.inc @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * Contains menu item registration for the content tool. + * + * The menu items registered are AJAX callbacks for the things like + * autocomplete and other tools needed by the content types. + */ + +function ctools_content_menu(&$items) { + $base = array( + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + 'file' => 'includes/content.menu.inc', + ); + $items['ctools/autocomplete/node'] = array( + 'page callback' => 'ctools_content_autocomplete_node', + ) + $base; +} + +/** + * Helper function for autocompletion of node titles. + */ +function ctools_content_autocomplete_node($string) { + if ($string != '') { + $preg_matches = array(); + $match = preg_match('/\[nid: (\d+)\]/', $string, $preg_matches); + if (!$match) { + $match = preg_match('/^nid: (\d+)/', $string, $preg_matches); + } + if ($match) { + $arg = $preg_matches[1]; + $where = "n.nid = %d"; + } + else { + $arg = $string; + $where = "LOWER(n.title) LIKE LOWER('%%%s%%')"; + } + if (!user_access('administer nodes')) { + $where .= ' AND n.status = 1'; + } + + $result = db_query_range(db_rewrite_sql("SELECT n.nid, n.title, u.name FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE $where"), $arg, 0, 10); + + $matches = array(); + while ($node = db_fetch_object($result)) { + $matches[$node->title . " [nid: $node->nid]"] = '<span class="autocomplete_title">' . check_plain($node->title) . '</span>'; + } + drupal_json($matches); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.theme.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..5ce1ea41f832c6c7e479cc93a5fa2714a84a245f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/content.theme.inc @@ -0,0 +1,21 @@ +<?php + +/** + * @file + * Contains theme registry and theme implementations for the content types. + */ + +/** + * Implementation of hook_theme to load all content plugins and pass thru if + * necessary. + */ +function ctools_content_theme(&$theme) { + ctools_include('content'); + + $plugins = ctools_get_content_types(); + foreach ($plugins as $plugin) { + if ($function = ctools_plugin_get_function($plugin, 'hook theme')) { + $function($theme, $plugin); + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-access-admin.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-access-admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..4e1baeb954cc311df8295d179e33823816043c57 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-access-admin.inc @@ -0,0 +1,482 @@ +<?php + +/** + * @file + * Contains administrative screens for the access control plugins. + * + * Access control can be implemented by creating a list of 0 or more access + * plugins, each with settings. This list can be ANDed together or ORed + * together. When testing access, each plugin is tested until success + * or failure can be determined. We use short circuiting techniques to + * ensure we are as efficient as possible. + * + * Access plugins are part of the context system, and as such can require + * contexts to work. That allows the use of access based upon visibility + * of an object, or even more esoteric things such as node type, node language + * etc. Since a lot of access depends on the logged in user, the logged in + * user should always be provided as a context. + * + * In the UI, the user is presented with a table and a 'add access method' select. + * When added, the user will be presented with the config wizard and, when + * confirmed, table will be refreshed via AJAX to show the new access method. + * Each item in the table will have controls to change the settings or remove + * the item. Changing the settings will invoke the modal for update. + * + * Currently the modal is not degradable, but it could be with only a small + * amount of work. + * + * A simple radio + * control is used to let the user pick the and/or logic. + * + * Access control is stored in an array: + * @code + * array( + * 'plugins' => array( + * 0 => array( + * 'name' => 'name of access plugin', + * 'settings' => array(), // These will be set by the form + * ), + * // ... as many as needed + * ), + * 'logic' => 'AND', // or 'OR', + * ), + * @endcode + * + * To add this widget to your UI, you need to do a little bit of setup. + * + * The form will utilize two callbacks, one to get the cached version + * of the access settings, and one to store the cached version of the + * access settings. These will be used from AJAX forms, so they will + * be completely out of the context of this page load and will not have + * knowledge of anything sent to this form (the 'module' and 'argument' + * will be preserved through the URL only). + * + * The 'module' is used to determine the location of the callback. It + * does not strictly need to be a module, so that if your module defines + * multiple systems that use this callback, it can use anything within the + * module's namespace it likes. + * + * When retrieving the cache, the cache may not have already been set up; + * In order to efficiently use cache space, we want to cache the stored + * settings *only* when they have changed. Therefore, the get access cache + * callback should first look for cache, and if it finds nothing, return + * the original settings. + * + * The callbacks: + * - $module . _ctools_access_get($argument) -- get the 'access' settings + * from cache. Must return array($access, $contexts); This callback can + * perform access checking to make sure this URL is not being gamed. + * - $module . _ctools_access_set($argument, $access) -- set the 'access' + * settings in cache. + * - $module . _ctools_access_clear($argument) -- clear the cache. + * + * The ctools_object_cache is recommended for this purpose, but you can use + * any caching mechanism you like. An example: + * + * @code{ + * ctools_include('object-cache'); + * ctools_object_cache_set("$module:argument", $access); + * } + * + * To utilize this form: + * @code + * ctools_include('context-access-admin'); + * ctools_include('form'), + * $form_state = array( + * 'access' => $access, + * 'module' => 'module name', + * 'callback argument' => 'some string', + * 'contexts' => $contexts, // an array of contexts. Optional if no contexts. + * // 'logged-in-user' will be added if not present as the access system + * // requires this context. + * ), + * $output = ctools_build_form('ctools_access_admin_form', $form_state); + * if (!empty($form_state['executed'])) { + * // save $form_state['access'] however you like. + * } + * @endcode + * + * Additionally, you may add 'no buttons' => TRUE if you wish to embed this + * form into your own, and instead call + * + * @code{ + * $form = array_merge($form, ctools_access_admin_form($form_state)); + * } + * + * You'll be responsible for adding a submit button. + * + * You may use ctools_access($access, $contexts) which will return + * TRUE if access is passed or FALSE if access is not passed. + */ + +/** + * Administrative form for access control. + */ +function ctools_access_admin_form(&$form_state) { + ctools_include('context'); + $argument = isset($form_state['callback argument']) ? $form_state['callback argument'] : ''; + $fragment = $form_state['module']; + if ($argument) { + $fragment .= '-' . $argument; + } + + $contexts = isset($form_state['contexts']) ? $form_state['contexts'] : array(); + + $form['access_table'] = array( + '#value' => ctools_access_admin_render_table($form_state['access'], $fragment, $contexts), + ); + + $form['add-button'] = array( + '#theme' => 'ctools_access_admin_add', + ); + // This sets up the URL for the add access modal. + $form['add-button']['add-url'] = array( + '#attributes' => array('class' => "ctools-access-add-url"), + '#type' => 'hidden', + '#value' => url("ctools/context/ajax/access/add/$fragment", array('absolute' => TRUE)), + ); + + $plugins = ctools_get_relevant_access_plugins($contexts); + $options = array(); + foreach ($plugins as $id => $plugin) { + $options[$id] = $plugin['title']; + } + + asort($options); + + $form['add-button']['type'] = array( + // This ensures that the form item is added to the URL. + '#attributes' => array('class' => "ctools-access-add-url"), + '#type' => 'select', + '#options' => $options, + ); + + $form['add-button']['add'] = array( + '#type' => 'submit', + '#attributes' => array('class' => 'ctools-use-modal'), + '#id' => "ctools-access-add", + '#value' => t('Add'), + ); + + $form['logic'] = array( + '#type' => 'radios', + '#options' => array( + 'and' => t('All criteria must pass.'), + 'or' => t('Only one criteria must pass.'), + ), + '#default_value' => isset($form_state['access']['logic']) ? $form_state['access']['logic'] : 'and', + ); + + if (empty($form_state['no buttons'])) { + $form['buttons']['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + '#submit' => array('ctools_access_admin_form_submit'), + ); + } + + return $form; +} + +/** + * Render the table. This is used both to render it initially and to rerender + * it upon ajax response. + */ +function ctools_access_admin_render_table($access, $fragment, $contexts) { + ctools_include('ajax'); + ctools_include('modal'); + $rows = array(); + + if (empty($access['plugins'])) { + $access['plugins'] = array(); + } + + foreach ($access['plugins'] as $id => $test) { + $row = array(); + $plugin = ctools_get_access_plugin($test['name']); + $title = isset($plugin['title']) ? $plugin['title'] : t('Broken/missing access plugin %plugin', array('%plugin' => $test['name'])); + + $row[] = array('data' => $title, 'class' => 'ctools-access-title'); + + $description = ctools_access_summary($plugin, $contexts, $test); + $row[] = array('data' => $description, 'class' => 'ctools-access-description'); + + $operations = ctools_modal_image_button(ctools_image_path('icon-configure.png'), "ctools/context/ajax/access/configure/$fragment/$id", t('Configure settings for this item.')); + $operations .= ctools_ajax_image_button(ctools_image_path('icon-delete.png'), "ctools/context/ajax/access/delete/$fragment/$id", t('Remove this item.')); + + $row[] = array('data' => $operations, 'class' => 'ctools-access-operations', 'align' => 'right'); + + $rows[] = $row; + } + + $header = array( + array('data' => t('Title'), 'class' => 'ctools-access-title'), + array('data' => t('Description'), 'class' => 'ctools-access-description'), + array('data' => '', 'class' => 'ctools-access-operations', 'align' => 'right'), + ); + + if (empty($rows)) { + $rows[] = array(array('data' => t('No criteria selected, this test will pass.'), 'colspan' => count($header))); + } + + ctools_modal_add_js(); + return theme('table', $header, $rows, array('id' => 'ctools-access-table')); +} + +/** + * Theme the 'add' portion of the access form into a table. + */ +function theme_ctools_access_admin_add($form) { + $rows = array(array(drupal_render($form))); + $output = '<div class="container-inline">'; + $output .= theme('table', array(), $rows); + $output .= '</div>'; + return $output; +} + +function ctools_access_admin_form_submit($form, &$form_state) { + $form_state['access']['logic'] = $form_state['values']['logic']; + + $function = $form_state['module'] . '_ctools_access_clear'; + if (function_exists($function)) { + $function($form_state['argument']); + } +} + +// -------------------------------------------------------------------------- +// AJAX menu entry points. + +/** + * AJAX callback to add a new access test to the list. + */ +function ctools_access_ajax_add($fragment = NULL, $name = NULL) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + + if (empty($fragment) || empty($name)) { + ctools_ajax_render_error(); + } + + $plugin = ctools_get_access_plugin($name); + if (empty($plugin)) { + ctools_ajax_render_error(); + } + + // Separate the fragment into 'module' and 'argument' + if (strpos($fragment, '-') === FALSE) { + $module = $fragment; + $argument = NULL; + } + else { + list($module, $argument) = explode('-', $fragment, 2); + } + + $function = $module . '_ctools_access_get'; + if (!function_exists($function)) { + ctools_ajax_render_error(t('Missing callback hooks.')); + } + + list($access, $contexts) = $function($argument); + + // Make sure we have the logged in user context + if (!isset($contexts['logged-in-user'])) { + $contexts['logged-in-user'] = ctools_access_get_loggedin_context(); + } + + if (empty($access['plugins'])) { + $access['plugins'] = array(); + } + + $test = ctools_access_new_test($plugin); + + $id = $access['plugins'] ? max(array_keys($access['plugins'])) + 1 : 0; + $access['plugins'][$id] = $test; + + $form_state = array( + 'plugin' => $plugin, + 'id' => $id, + 'test' => &$access['plugins'][$id], + 'access' => &$access, + 'contexts' => $contexts, + 'title' => t('Add criteria'), + 'ajax' => TRUE, + ); + + $output = ctools_modal_form_wrapper('ctools_access_ajax_edit_item', $form_state); + if (empty($output)) { + $function = $module . '_ctools_access_set'; + if (function_exists($function)) { + $function($argument, $access); + } + + $table = ctools_access_admin_render_table($access, $fragment, $contexts); + $output = array(); + $output[] = ctools_ajax_command_replace('table#ctools-access-table', $table); + $output[] = ctools_modal_command_dismiss(); + } + + ctools_ajax_render($output); +} + +/** + * AJAX callback to edit an access test in the list. + */ +function ctools_access_ajax_edit($fragment = NULL, $id = NULL) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + + if (empty($fragment) || !isset($id)) { + ctools_ajax_render_error(); + } + + // Separate the fragment into 'module' and 'argument' + if (strpos($fragment, '-') === FALSE) { + $module = $fragment; + $argument = NULL; + } + else { + list($module, $argument) = explode('-', $fragment, 2); + } + + $function = $module . '_ctools_access_get'; + if (!function_exists($function)) { + ctools_ajax_render_error(t('Missing callback hooks.')); + } + + list($access, $contexts) = $function($argument); + + if (empty($access['plugins'][$id])) { + ctools_ajax_render_error(); + } + + // Make sure we have the logged in user context + if (!isset($contexts['logged-in-user'])) { + $contexts['logged-in-user'] = ctools_access_get_loggedin_context(); + } + + $plugin = ctools_get_access_plugin($access['plugins'][$id]['name']); + $form_state = array( + 'plugin' => $plugin, + 'id' => $id, + 'test' => &$access['plugins'][$id], + 'access' => &$access, + 'contexts' => $contexts, + 'title' => t('Edit criteria'), + 'ajax' => TRUE, + ); + + $output = ctools_modal_form_wrapper('ctools_access_ajax_edit_item', $form_state); + if (empty($output)) { + $function = $module . '_ctools_access_set'; + if (function_exists($function)) { + $function($argument, $access); + } + + $table = ctools_access_admin_render_table($access, $fragment, $contexts); + $output = array(); + $output[] = ctools_ajax_command_replace('table#ctools-access-table', $table); + $output[] = ctools_modal_command_dismiss(); + } + + ctools_ajax_render($output); +} + +/** + * Form to edit the settings of an access test. + */ +function ctools_access_ajax_edit_item(&$form_state) { + $test = &$form_state['test']; + $plugin = &$form_state['plugin']; + + if (isset($plugin['required context'])) { + $form['context'] = ctools_context_selector($form_state['contexts'], $plugin['required context'], $test['context']); + } + $form['settings'] = array('#tree' => TRUE); + if ($function = ctools_plugin_get_function($plugin, 'settings form')) { + $function($form, $form_state, $test['settings']); + } + + $form['not'] = array( + '#type' => 'checkbox', + '#title' => t('Reverse (NOT)'), + '#default_value' => !empty($test['not']), + ); + + $form['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +/** + * Validate handler for argument settings. + */ +function ctools_access_ajax_edit_item_validate(&$form, &$form_state) { + if ($function = ctools_plugin_get_function($form_state['plugin'], 'settings form validate')) { + $function($form, $form_state); + } +} + +/** + * Submit handler for argument settings. + */ +function ctools_access_ajax_edit_item_submit(&$form, &$form_state) { + if ($function = ctools_plugin_get_function($form_state['plugin'], 'settings form submit')) { + $function($form, $form_state); + } + + $form_state['test']['settings'] = $form_state['values']['settings']; + if (isset($form_state['values']['context'])) { + $form_state['test']['context'] = $form_state['values']['context']; + } + $form_state['test']['not'] = !empty($form_state['values']['not']); +} + +/** + * AJAX command to remove an access control item. + */ +function ctools_access_ajax_delete($fragment = NULL, $id = NULL) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + + if (empty($fragment) || !isset($id)) { + ctools_ajax_render_error(); + } + + // Separate the fragment into 'module' and 'argument' + if (strpos($fragment, '-') === FALSE) { + $module = $fragment; + $argument = NULL; + } + else { + list($module, $argument) = explode('-', $fragment, 2); + } + + $function = $module . '_ctools_access_get'; + if (!function_exists($function)) { + ctools_ajax_render_error(t('Missing callback hooks.')); + } + + list($access, $contexts) = $function($argument); + + if (isset($access['plugins'][$id])) { + unset($access['plugins'][$id]); + } + + // re-cache + $function = $module . '_ctools_access_set'; + if (function_exists($function)) { + $function($argument, $access); + } + + $table = ctools_access_admin_render_table($access, $fragment, $contexts); + $output = array(); + $output[] = ctools_ajax_command_replace('table#ctools-access-table', $table); + + ctools_ajax_render($output); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-admin.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..727a25999b5417b5f64a1d8a4c4f4f43db11a218 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-admin.inc @@ -0,0 +1,1008 @@ +<?php + +/** + * @file includes/common-context.inc + * Provide API for adding contexts for modules that embed displays. + * + * Note that most of this code was directly copied from Panels 2, and as such + * a lot of this code is crusty. It could probably stand to be rewritten, + * and brought up to date, or at least better commented. + */ + +/** + * Provide a list of the ways contexts can be embedded. + * + * This provides a full list of context types that the tool understands + * and can let modules utilize. + */ +function ctools_context_info($type = NULL) { + static $info = NULL; + + // static doesn't work with functions like t(). + if (empty($info)) { + $info = array( + 'argument' => array( + 'title' => t('Arguments'), + 'singular title' => t('argument'), + 'description' => '', // t("Arguments are parsed from the URL and translated into contexts that may be added to the display via the 'content' tab. These arguments are parsed in the order received, and you may use % in your URL to hold the place of an object; the rest of the arguments will come after the URL. For example, if the URL is node/%/panel and your user visits node/1/panel/foo, the first argument will be 1, and the second argument will be foo."), + 'add button' => t('Add argument'), + 'context function' => 'ctools_get_argument', + 'form id' => 'ctools_edit_argument_form', + 'key' => 'arguments', // the key that data will be stored on an object, eg $panel_page + 'sortable' => TRUE, + 'settings' => 'argument_settings', + ), + 'relationship' => array( + 'title' => t('Relationships'), + 'singular title' => t('relationship'), + 'description' => '', // t('Relationships are contexts that are created from already existing contexts; the add relationship button will only appear once there is another context available. Relationships can load objects based upon how they are related to each other; for example, the author of a node, or a taxonomy term attached to a node, or the vocabulary of a taxonomy term.'), + 'add button' => t('Add relationship'), + 'context function' => 'ctools_get_relationship', + 'form id' => 'ctools_edit_relationship_form', + 'key' => 'relationships', + 'sortable' => FALSE, + 'settings' => 'relationship_settings', + ), + 'context' => array( + 'title' => t('Contexts'), + 'singular title' => t('context'), + 'description' => '', // t('Contexts are embedded directly into the panel; you generally must select an object in the panel. For example, you could select node 5, or the term "animals" or the user "administrator"'), + 'add button' => t('Add context'), + 'context function' => 'ctools_get_context', + 'form id' => 'ctools_edit_context_form', + 'key' => 'contexts', + 'sortable' => FALSE, + 'settings' => 'context_settings', + ), + 'requiredcontext' => array( + 'title' => t('Required contexts'), + 'singular title' => t('required context'), + 'description' => '', // t('Required contexts are passed in from some external source, such as a containing panel. If a mini panel has required contexts, it can only appear when that context is available, and therefore will not show up as a standard Drupal block.'), + 'add button' => t('Add required context'), + 'context function' => 'ctools_get_context', + 'form id' => 'ctools_edit_requiredcontext_form', + 'key' => 'requiredcontexts', + 'sortable' => FALSE, + ), + ); + } + + if ($type === NULL) { + return $info; + } + + return $info[$type]; +} + +/** + * Get the cache for the context object. + * + * This can pass through to a module provided cache if it exists, or + * the default cache will be used. + */ +function ctools_context_cache_get($fragment, $key) { + // Separate the fragment into 'module' and 'argument' + if (strpos($fragment, '-') === FALSE) { + $module = $fragment; + $argument = NULL; + } + else { + list($module, $argument) = explode('-', $fragment, 2); + } + + $function = $module . '_context_cache_get'; + if (function_exists($function)) { + return $function($argument, $key); + } + else { + return ctools_object_cache_get("context_object:$module", $key); + } +} + +/** + * Get the cache for the context object. + * + * This can pass through to a module provided cache if it exists, or + * the default cache will be used. + */ +function ctools_context_cache_set($fragment, $key, $object) { + // Separate the fragment into 'module' and 'argument' + if (strpos($fragment, '-') === FALSE) { + $module = $fragment; + $argument = NULL; + } + else { + list($module, $argument) = explode('-', $fragment, 2); + } + + $function = $module . '_context_cache_set'; + if (function_exists($function)) { + return $function($argument, $key, $object); + } + else { + return ctools_object_cache_set("context_object:$module", $key, $object); + } +} + +/** + * Get the data belonging to a particular context. + */ +function ctools_context_data($type, $name) { + $info = ctools_context_info($type); + if (function_exists($info['context function'])) { + return $info['context function']($name); + } +} + +/** + * Add the argument table plus gadget plus javascript to the form. + */ +function ctools_context_add_argument_form($module, &$form, &$form_state, &$form_location, $object, $name = NULL) { + if (empty($name)) { + $name = $object->name; + } + + $form_location = array( + '#prefix' => '<div id="ctools-arguments-table">', + '#suffix' => '</div>', + '#theme' => 'ctools_context_item_form', + '#object_name' => $name, + '#ctools_context_type' => 'argument', + '#ctools_context_module' => $module, + ); + + $args = ctools_get_arguments(); + $choices = array(); + foreach ($args as $name => $arg) { + $choices[$name] = $arg['title']; + } + + asort($choices); + + if (!empty($choices) || !empty($object->arguments)) { + ctools_context_add_item_table('argument', $form_location, $choices, $object->arguments); + } +} + +function ctools_context_add_context_form($module, &$form, &$form_state, &$form_location, $object, $name = NULL) { + if (empty($name)) { + $name = $object->name; + } + + $form_location = array( + '#prefix' => '<div id="ctools-contexts-table">', + '#suffix' => '</div>', + '#theme' => 'ctools_context_item_form', + '#object_name' => $name, + '#ctools_context_type' => 'context', + '#ctools_context_module' => $module, + ); + + // Store the order the choices are in so javascript can manipulate it. + $form_location['markup'] = array( + '#value' => ' ', + ); + + $choices = array(); + foreach (ctools_get_contexts() as $name => $arg) { + if (empty($arg['no ui'])) { + $choices[$name] = $arg['title']; + } + } + + asort($choices); + + if (!empty($choices) || !empty($object->contexts)) { + ctools_context_add_item_table('context', $form_location, $choices, $object->contexts); + } +} + +function ctools_context_add_required_context_form($module, &$form, &$form_state, &$form_location, $object, $name = NULL) { + if (empty($name)) { + $name = $object->name; + } + + $form_location = array( + '#prefix' => '<div id="ctools-requiredcontexts-table">', + '#suffix' => '</div>', + '#theme' => 'ctools_context_item_form', + '#object_name' => $name, + '#ctools_context_type' => 'requiredcontext', + '#ctools_context_module' => $module, + ); + + // Store the order the choices are in so javascript can manipulate it. + $form_location['markup'] = array( + '#value' => ' ', + ); + + $choices = array(); + foreach (ctools_get_contexts() as $name => $arg) { + $choices[$name] = $arg['title']; + } + + asort($choices); + + if (!empty($choices) || !empty($object->contexts)) { + ctools_context_add_item_table('requiredcontext', $form_location, $choices, $object->requiredcontexts); + } +} + +function ctools_context_add_relationship_form($module, &$form, &$form_state, &$form_location, $object, $name = NULL) { + if (empty($name)) { + $name = $object->name; + } + + $form_location = array( + '#prefix' => '<div id="ctools-relationships-table">', + '#suffix' => '</div>', + '#theme' => 'ctools_context_item_form', + '#object_name' => $name, + '#ctools_context_type' => 'relationship', + '#ctools_context_module' => $module, + ); + + // Store the order the choices are in so javascript can manipulate it. + $form_location['markup'] = array( + '#value' => ' ', + ); + + $base_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); + $available_relationships = ctools_context_get_relevant_relationships(ctools_context_load_contexts($object, TRUE, $base_contexts)); + + ctools_context_add_item_table('relationship', $form_location, $available_relationships, $object->relationships); +} + +/** + * Include all context administrative include files, css, javascript. + */ +function ctools_context_admin_includes() { + ctools_include('context'); + ctools_include('modal'); + ctools_include('ajax'); + ctools_include('object-cache'); + ctools_modal_add_js(); + ctools_modal_add_plugin_js(ctools_get_contexts()); + ctools_modal_add_plugin_js(ctools_get_relationships()); +} + +/** + * Add the context table to the page. + */ +function ctools_context_add_item_table($type, &$form, $available_contexts, $items) { + $form[$type] = array( + '#tree' => TRUE, + ); + + $module = $form['#ctools_context_module']; + $name = $form['#object_name']; + + if (isset($items) && is_array($items)) { + foreach ($items as $position => $context) { + ctools_context_add_item_to_form($module, $type, $name, $form[$type][$position], $position, $context); + } + } + + $type_info = ctools_context_info($type); + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => $type_info['description'], + ); + + ctools_context_add_item_table_buttons($type, $module, $form, $available_contexts); +} + +function ctools_context_add_item_table_buttons($type, $module, &$form, $available_contexts) { + $form['buttons'] = array( + '#tree' => TRUE, + ); + + if (!empty($available_contexts)) { + $type_info = ctools_context_info($type); + + $module = $form['#ctools_context_module']; + $name = $form['#object_name']; + + // The URL for this ajax button + $form['buttons'][$type]['add-url'] = array( + '#attributes' => array('class' => "ctools-$type-add-url"), + '#type' => 'hidden', + '#value' => url("ctools/context/ajax/add/$module/$type/$name", array('absolute' => TRUE)), + ); + + // This also will be in the URL. + $form['buttons'][$type]['item'] = array( + '#attributes' => array('class' => "ctools-$type-add-url"), + '#type' => 'select', + '#options' => $available_contexts, + ); + + $form['buttons'][$type]['add'] = array( + '#type' => 'submit', + '#attributes' => array('class' => 'ctools-use-modal'), + '#id' => "ctools-$type-add", + '#value' => $type_info['add button'], + ); + } +} + +/** + * Add a row to the form. Used both in the main form and by + * the ajax to add an item. + */ +function ctools_context_add_item_to_form($module, $type, $name, &$form, $position, $item) { + // This is the single function way to load any plugin by variable type. + $info = ctools_context_data($type, $item['name']); + $form['title'] = array( + '#value' => check_plain($item['identifier']), + ); + + // Relationships not sortable. + $type_info = ctools_context_info($type); + + if (!empty($type_info['sortable'])) { + $form['position'] = array( + '#type' => 'weight', + '#default_value' => $position, + '#attributes' => array('class' => 'drag-position'), + ); + } + + $form['remove'] = array( + '#value' => ctools_ajax_image_button(ctools_image_path('icon-delete.png'), "ctools/context/ajax/delete/$module/$type/$name/$position", t('Remove this item.')), + ); + + $form['settings'] = array( + '#value' => ctools_modal_image_button(ctools_image_path('icon-configure.png'), "ctools/context/ajax/configure/$module/$type/$name/$position", t('Configure settings for this item.')), + ); +} + + +// --------------------------------------------------------------------------- +// AJAX forms and stuff. + +/** + * Ajax entry point to add an context + */ +function ctools_context_ajax_item_add($module = NULL, $type = NULL, $object_name = NULL, $name = NULL) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + ctools_include('object-cache'); + + if (!$name) { + return ctools_ajax_render_error(); + } + + // Load stored object from cache. + if (!($object = ctools_context_cache_get($module, $object_name))) { + ctools_ajax_render_error(t('Invalid object name.')); + } + + // Get info about what we're adding. + $info = ctools_context_data($type, $name); + if (empty($info)) { + return ctools_ajax_render_error(); + } + $type_info = ctools_context_info($type); + + // Create a reference to the place our context lives. Since this is fairly + // generic, this is the easiest way to get right to the place of the + // object without knowing precisely what data we're poking at. + $ref = &$object->{$type_info['key']}; + + // Give this item an id, which is really just the nth version + // of this particular context. + $id = ctools_context_next_id($ref, $name); + + // Figure out the position for our new context. + $position = empty($ref) ? 0 : max(array_keys($ref)) + 1; + + // Create the basis for our new context. + $ref[$position] = array( + 'identifier' => $info['title'] . ($id > 1 ? ' ' . $id : ''), + 'keyword' => ctools_get_keyword($object, $info['keyword']), + 'id' => $id, + 'name' => $name, + ); + + if (isset($type_info['settings'])) { + $ref[$position][$type_info['settings']] = isset($info['defaults']) ? $info['defaults'] : array(); + } + + $base_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); + $contexts = ctools_context_load_contexts($object, TRUE, $base_contexts); + + $form_state = array( + 'object' => &$object, + 'module' => $module, + 'type' => $type, + 'name' => $name, + 'ajax' => TRUE, + 'info' => $info, + 'position' => $position, + 'contexts' => $contexts, + 'ref' => &$ref, + 'title' => t('Add @type "@context"', array('@type' => $type_info['singular title'], '@context' => $info['title'])), + ); + + $output = ctools_modal_form_wrapper($type_info['form id'], $form_state); + + if (empty($output)) { + // successful submit + ctools_context_cache_set($module, $object_name, $object); + + $arg_form_state = array(); + + $arg_form = array( + '#post' => array(), + '#programmed' => FALSE, + '#tree' => FALSE, + ); + + // Build a chunk of the form to merge into the displayed form + $arg_form[$type] = array( + '#tree' => TRUE, + ); + $arg_form[$type][$position] = array( + '#tree' => TRUE, + ); + + ctools_context_add_item_to_form($module, $type, $object_name, $arg_form[$type][$position], $position, $ref[$position]); + $arg_form = form_builder($type_info['form id'], $arg_form, $arg_form_state); + + // Build the relationships table so we can ajax it in. + // This is an additional thing that goes in here. + $rel_form = array( + '#theme' => 'ctools_context_item_form', + '#object_name' => $object_name, + '#ctools_context_type' => 'relationship', + '#ctools_context_module' => $module, + '#only_buttons' => TRUE, + '#post' => array(), + '#programmed' => FALSE, + '#tree' => FALSE, + ); + + $rel_form['relationship'] = array( + '#tree' => TRUE, + ); + + // Allow an object to set some 'base' contexts that come from elsewhere. + $rel_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); + $all_contexts = ctools_context_load_contexts($object, TRUE, $rel_contexts); + $available_relationships = ctools_context_get_relevant_relationships($all_contexts); + + $output = array(); + if (!empty($available_relationships)) { + ctools_context_add_item_table_buttons('relationship', $module, $rel_form, $available_relationships); + $rel_form = form_builder('dummy_form_id', $rel_form, $arg_form_state); + $output[] = ctools_ajax_command_replace('div#ctools-relationships-table div.buttons', drupal_render($rel_form)); + } + + $text = theme('ctools_context_item_row', $type, $arg_form[$type][$position], $position, $position); + $output[] = ctools_ajax_command_append('#' . $type . '-table tbody', $text); + $output[] = ctools_ajax_command_changed('#' . $type . '-row-' . $position, '.title'); + $output[] = ctools_modal_command_dismiss(); + } + + ctools_ajax_render($output); +} + +/** + * Ajax entry point to edit an item + */ +function ctools_context_ajax_item_edit($module = NULL, $type = NULL, $object_name = NULL, $position = NULL) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + ctools_include('object-cache'); + + if (!isset($position)) { + return ctools_ajax_render_error(); + } + + // Load stored object from cache. + if (!($object = ctools_context_cache_get($module, $object_name))) { + ctools_ajax_render_error(t('Invalid object name.')); + } + + $type_info = ctools_context_info($type); + + // Create a reference to the place our context lives. Since this is fairly + // generic, this is the easiest way to get right to the place of the + // object without knowing precisely what data we're poking at. + $ref = &$object->{$type_info['key']}; + + $name = $ref[$position]['name']; + if (empty($name)) { + ctools_ajax_render_error(); + } + + // load the context + $info = ctools_context_data($type, $name); + if (empty($info)) { + ctools_ajax_render_error(t('Invalid context type')); + } + + $base_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); + $contexts = ctools_context_load_contexts($object, TRUE, $base_contexts); + + // Remove this context, because we can't really allow circular contexts. + unset($contexts[ctools_context_id($ref[$position])]); + + $form_state = array( + 'object' => &$object, + 'module' => $module, + 'type' => $type, + 'name' => $name, + 'ajax' => TRUE, + 'info' => $info, + 'position' => $position, + 'contexts' => $contexts, + 'ref' => &$ref, + 'title' => t('Edit @type "@context"', array('@type' => $type_info['singular title'], '@context' => $info['title'])), + ); + + $output = ctools_modal_form_wrapper($type_info['form id'], $form_state); + + if (empty($output)) { + // successful submit + ctools_context_cache_set($module, $object_name, $object); + + $output = array(); + $output[] = ctools_modal_command_dismiss(); + + $arg_form = array( + '#post' => array(), + '#programmed' => FALSE, + '#tree' => FALSE, + ); + + // Build a chunk of the form to merge into the displayed form + $arg_form[$type] = array( + '#tree' => TRUE, + ); + $arg_form[$type][$position] = array( + '#tree' => TRUE, + ); + + ctools_context_add_item_to_form($module, $type, $object_name, $arg_form[$type][$position], $position, $ref[$position]); + $arg_form = form_builder($type_info['form id'], $arg_form, $arg_form_state); + + $output[] = ctools_ajax_command_replace('#' . $type . '-row-' . $position, theme('ctools_context_item_row', $type, $arg_form[$type][$position], $position, $position)); + $output[] = ctools_ajax_command_changed('#' . $type . '-row-' . $position, '.title'); + } + ctools_ajax_render($output); +} + +/** + * Form (for ajax use) to add a context + */ +function ctools_edit_context_form(&$form_state) { + $object = $form_state['object']; + $context = $form_state['info']; + $position = $form_state['position']; + $contexts = $form_state['contexts']; + + $ctext = $object->contexts[$position]; + + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => check_plain($context['description']), + ); + + // Basic context values + $form['context']['#tree'] = TRUE; + + $form['context']['name'] = array( + '#type' => 'hidden', + '#value' => $context['name'], + ); + + $form['context']['id'] = array( + '#type' => 'hidden', + '#value' => $ctext['id'], + ); + + $form['context']['identifier'] = array( + '#type' => 'textfield', + '#title' => t('Identifier'), + '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' => t('context'))), + '#default_value' => $ctext['identifier'], + ); + + $form['context']['keyword'] = array( + '#type' => 'textfield', + '#title' => t('Keyword'), + '#description' => t('Enter a keyword to use for substitution in titles.'), + '#default_value' => $ctext['keyword'], + ); + + // Settings particular to this context + $context_settings = array(); + if (isset($ctext['context_settings'])) { + $context_settings = $ctext['context_settings']; + } + + if (isset($context['settings form']) && function_exists($context['settings form'])) { + $form['context']['context_settings'] = $context['settings form']($context_settings); + $form['context']['context_settings']['#tree'] = TRUE; + } + + $form['next'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + return $form; +} + +/** + * validate a context edited/added via ajax + */ +function ctools_edit_context_form_validate($form, &$form_state) { + $context = $form_state['info']; + + if (isset($context['settings form validate']) && function_exists($context['settings form validate'])) { + $context['settings form validate']($form['context']['context_settings'], $form_state['values']['context']['context_settings'], $form_state); + } +} + +/** + * Updates an context edited/added via ajax + */ +function ctools_edit_context_form_submit($form, &$form_state) { + $info = $form_state['info']; + + if (isset($info['settings form submit']) && function_exists($info['settings form submit'])) { + $info['settings form submit']($form, $form_state['values']['context']['context_settings'], $form_state); + } + + $context = $form_state['values']['context']; + $form_state['ref'][$form_state['position']] = $context; +} + +/** + * Form (for ajax use) to add a context + */ +function ctools_edit_requiredcontext_form(&$form_state) { + $object = $form_state['object']; + $context = $form_state['info']; + $position = $form_state['position']; + $contexts = $form_state['contexts']; + + $ctext = $object->requiredcontexts[$position]; + $form['start_form'] = array('#value' => '<div class="modal-form clear-block">'); + + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => check_plain($context['description']), + ); + + // Basic context values + $form['requiredcontext']['#tree'] = TRUE; + + $form['requiredcontext']['name'] = array( + '#type' => 'hidden', + '#value' => $context['name'], + ); + + $form['requiredcontext']['id'] = array( + '#type' => 'hidden', + '#value' => $ctext['id'], + ); + + $form['requiredcontext']['identifier'] = array( + '#type' => 'textfield', + '#title' => t('Identifier'), + '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' => t('required context'))), + '#default_value' => $ctext['identifier'], + ); + + $form['requiredcontext']['keyword'] = array( + '#type' => 'textfield', + '#title' => t('Keyword'), + '#description' => t('Enter a keyword to use for substitution in titles.'), + '#default_value' => $ctext['keyword'], + ); + + $form['end_form'] = array('#value' => '</div>'); + + $form['next'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + return $form; +} + +/** + * Updates a required context edited/added via ajax + */ +function ctools_edit_requiredcontext_form_submit($form, &$form_state) { + $form_state['ref'][$form_state['position']] = $form_state['values']['requiredcontext']; +} + +/** + * Form (for ajax use) to add a relationship + */ +function ctools_edit_relationship_form(&$form_state) { + $object = $form_state['object']; + $relationship = $form_state['info']; + $position = $form_state['position']; + $contexts = $form_state['contexts']; + + $rel = $object->relationships[$position]; + + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => check_plain($relationship['description']), + ); + + // Basic relationship values + $form['relationship']['#tree'] = TRUE; + + $form['relationship']['context'] = ctools_context_selector($contexts, $relationship['required context'], isset($rel['context']) ? $rel['context'] : ''); + + $form['relationship']['name'] = array( + '#type' => 'hidden', + '#value' => $relationship['name'], + ); + + $form['relationship']['id'] = array( + '#type' => 'hidden', + '#value' => $rel['id'], + ); + + $form['relationship']['identifier'] = array( + '#type' => 'textfield', + '#title' => t('Identifier'), + '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' => t('relationship'))), + '#default_value' => $rel['identifier'], + ); + + $form['relationship']['keyword'] = array( + '#type' => 'textfield', + '#title' => t('Keyword'), + '#description' => t('Enter a keyword to use for substitution in titles.'), + '#default_value' => $rel['keyword'], + ); + + // Settings particular to this relationship + $relationship_settings = array(); + if (isset($rel['relationship_settings'])) { + $relationship_settings = $rel['relationship_settings']; + } + + if (isset($relationship['settings form']) && function_exists($relationship['settings form'])) { + $form['relationship']['relationship_settings'] = $relationship['settings form']($relationship_settings); + $form['relationship']['relationship_settings']['#tree'] = TRUE; + } + + $form['next'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + return $form; +} + +/** + * validate an relationship edited/added via ajax + */ +function ctools_edit_relationship_form_validate($form, &$form_state) { + $relationship = $form_state['info']; + + if (isset($relationship['settings form validate']) && function_exists($relationship['settings form validate'])) { + $relationship['settings form validate']($form['relationship']['relationship_settings'], $form_state['values']['relationship']['relationship_settings'], $form_state); + } +} + +/** + * Updates an relationship edited/added via ajax + */ +function ctools_edit_relationship_form_submit($form, &$form_state) { + $relationship = $form_state['info']; + + if (isset($relationship['settings form submit']) && function_exists($relationship['settings form submit'])) { + $relationship['settings form submit']($form, $form_state['values']['relationship']['relationship_settings'], $form_state); + } + + $form_state['ref'][$form_state['position']] = $form_state['values']['relationship']; +} + +/** + * Form (for ajax use) to add an argument + */ +function ctools_edit_argument_form(&$form_state) { + // Basic values required to orient ourselves + $object = $form_state['object']; + $argument = $form_state['info']; + $position = $form_state['position']; + $contexts = $form_state['contexts']; + + $arg = $object->arguments[$position]; + + if (!isset($arg['default'])) { + $arg['default'] = 'ignore'; + $arg['title'] = ''; + } + + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => check_plain($argument['description']), + ); + + // Basic argument values + $form['argument']['#tree'] = TRUE; + + $form['argument']['name'] = array( + '#type' => 'hidden', + '#value' => $argument['name'], + ); + + $form['argument']['id'] = array( + '#type' => 'hidden', + '#value' => $arg['id'], + ); + + $form['argument']['default'] = array( + '#type' => 'select', + '#title' => t('Default'), + '#options' => array( + 'ignore' => t('Ignore it; content that requires this context will not be available.'), + '404' => t('Display page not found or display nothing at all.'), + ), + '#default_value' => $arg['default'], + '#description' => t('If the argument is missing or is not valid, select how this should behave.'), + ); + + $form['argument']['title'] = array( + '#type' => 'textfield', + '#title' => t('Title'), + '#default_value' => $arg['title'], + '#description' => t('Enter a title to use when this argument is present. You may use %KEYWORD substitution, where the keyword is specified below.'), + ); + + $form['argument']['identifier'] = array( + '#type' => 'textfield', + '#title' => t('Identifier'), + '#description' => t('Enter a name to identify this !type on administrative screens.', array('!type' => t('argument'))), + '#default_value' => $arg['identifier'], + ); + + $form['argument']['keyword'] = array( + '#type' => 'textfield', + '#title' => t('Keyword'), + '#description' => t('Enter a keyword to use for substitution in titles.'), + '#default_value' => $arg['keyword'], + ); + + // Settings particular to this argument + $argument_settings = array(); + if (isset($arg['argument_settings'])) { + $argument_settings = $arg['argument_settings']; + } + + + if (isset($argument['settings form']) && function_exists($argument['settings form'])) { + $form['argument']['argument_settings'] = $argument['settings form']($argument_settings); + } + $form['argument']['argument_settings']['#tree'] = TRUE; + + $form['next'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +/** + * validate an argument edited/added via ajax + */ +function ctools_edit_argument_form_validate($form, &$form_state) { + $argument = $form_state['info']; + + if (isset($argument['settings form validate']) && function_exists($argument['settings form validate'])) { + $argument['settings form validate']($form, $form_state['values']['argument_settings'], $form_state); + } +} + +/** + * Updates an argument edited/added via ajax + */ +function ctools_edit_argument_form_submit($form, &$form_state) { + $argument = $form_state['info']; + + if (!isset($form_state['values']['argument_settings'])) { + $form_state['values']['argument_settings'] = array(); + } + + if (isset($argument['settings form submit']) && function_exists($argument['settings form submit'])) { + $argument['settings form submit']($form, $form_state['values']['argument_settings'], $form_state); + } + + $form_state['ref'][$form_state['position']] = $form_state['values']['argument']; +} + +/** + * Ajax entry point to edit an item + */ +function ctools_context_ajax_item_delete($module = NULL, $type = NULL, $object_name = NULL, $position = NULL) { + ctools_include('ajax'); + ctools_include('context'); + ctools_include('object-cache'); + + if (!isset($position)) { + return ctools_ajax_render_error(); + } + + // Load stored object from cache. + if (!($object = ctools_context_cache_get($module, $object_name))) { + ctools_ajax_render_error(t('Invalid object name.')); + } + + $type_info = ctools_context_info($type); + + // Create a reference to the place our context lives. Since this is fairly + // generic, this is the easiest way to get right to the place of the + // object without knowing precisely what data we're poking at. + $ref = &$object->{$type_info['key']}; + + if (!array_key_exists($position, $ref)) { + ctools_ajax_render_error(t('Unable to delete missing item!')); + } + + unset($ref[$position]); + ctools_context_cache_set($module, $object_name, $object); + + $output = array(); + $output[] = ctools_ajax_command_replace('#' . $type . '-row-' . $position, ''); + $output[] = ctools_ajax_command_restripe("#$type-table"); + ctools_ajax_render($output); +} + +// --- End of contexts + +function ctools_save_context($type, &$ref, $form_values) { + $type_info = ctools_context_info($type); + + // Organize arguments + $new = array(); + $order = array(); + + foreach ($ref as $id => $context) { + $position = $form_values[$type][$id]['position']; + $order[$position] = $id; + } + + ksort($order); + foreach ($order as $id) { + $new[] = $ref[$id]; + } + $ref = $new; +} + +function ctools_get_keyword($page, $word) { + // Create a complete set of keywords + $keywords = array(); + foreach (array('arguments', 'relationships', 'contexts', 'requiredcontexts') as $type) { + if (!empty($page->$type) && is_array($page->$type)) { + foreach ($page->$type as $info) { + $keywords[$info['keyword']] = TRUE; + } + } + } + + $keyword = $word; + $count = 0; + while (!empty($keywords[$keyword])) { + $keyword = $word . '_' . ++$count; + } + return $keyword; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-task-handler.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-task-handler.inc new file mode 100644 index 0000000000000000000000000000000000000000..4fed9d0391e9eefda1e5217bef89d65af8c2b23e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context-task-handler.inc @@ -0,0 +1,435 @@ +<?php + +/** + * @file + * Support for creating 'context' type task handlers. + * + * Context task handlers expect the task to provide 0 or more contexts. The + * task handler should use those contexts as selection rules, as well as + * rendering with them. + * + * The functions and forms in this file should be common to every context type + * task handler made. + * + * Forms: + * - ... + */ + +/** + * Render a context type task handler given a list of handlers + * attached to a type. + * + * @param $task + * The $task object in use. + * @param $subtask + * The id of the subtask in use. + * @param $contexts + * The context objects in use. + * @param $args + * The raw arguments behind the contexts. + * @param $page + * If TRUE then this renderer owns the page and can use theme('page') + * for no blocks; if false, output is returned regardless of any no + * blocks settings. + * @return + * Either the output or NULL if there was output, FALSE if no handler + * accepted the task. If $page is FALSE then the $info block is returned instead. + */ +function ctools_context_handler_render($task, $subtask, $contexts, $args, $page = TRUE) { + // Load the landlers, choosing only enabled handlers. + $handlers = page_manager_load_sorted_handlers($task, $subtask ? $subtask['name'] : '', TRUE); + + // Try each handler. + foreach ($handlers as $handler) { + if ($function = page_manager_get_renderer($handler)) { + if ($info = $function($handler, $contexts, $args)) { + drupal_alter('ctools_render', $info, $page, $args, $contexts, $task, $subtask, $handler); + // If we don't own the page, let the caller deal with rendering. + if (!$page) { + return $info; + } + + if ($subtask) { + $task_name = page_manager_make_task_name($task['name'], $subtask['name']); + } + else { + $task_name = $task['name']; + } + + page_manager_get_current_page(array( + 'name' => $task_name, + 'task' => $task, + 'subtask' => $subtask, + 'contexts' => $contexts, + 'arguments' => $args, + 'handler' => $handler, + )); + + if (!empty($info['response code']) && $info['response code'] != 200) { + switch ($info['response code']) { + case 403: + return MENU_ACCESS_DENIED; + case 404: + return MENU_NOT_FOUND; + case 301: + case 302: + case 303: + case 304: + case 305: + case 307: + $info += array( + 'query' => '', + 'fragment' => '', + ); + return drupal_goto($info['destination'], $info['query'], $info['fragment'], $info['response code']); + // @todo -- should other response codes be supported here? + } + } + + /* + // Only do this if something hasn't already changed the active menu, + // such as a book. + if (menu_get_active_menu_name() == 'navigation') { + $item = menu_get_item(); + $mlink = db_fetch_object(db_query("SELECT * FROM {menu_links} WHERE link_path = '%s'", $item['href'])); + + if ($mlink && isset($mlink->menu_name)) { + menu_set_active_menu_name($mlink->menu_name); + } + } + */ + foreach (ctools_context_handler_get_task_arguments($task, $subtask) as $id => $argument) { + $plugin = ctools_get_argument($argument['name']); + $cid = ctools_context_id($argument, 'argument'); + if (!empty($contexts[$cid]) && ($function = ctools_plugin_get_function($plugin, 'breadcrumb'))) { + $function($argument['settings'], $contexts[$cid]); + } + } + + if (isset($info['title'])) { + drupal_set_title($info['title']); + } + + // Only directly output if $page was set to true. + if (!empty($info['no_blocks'])) { + print theme('page', $info['content'], FALSE); + return; + } + else { + return $info['content']; + } + } + } + } + + return FALSE; +} + +/** + * Called to execute actions that should happen before a handler is rendered. + */ +function ctools_context_handler_pre_render($handler, $contexts, $args) { + $plugin = page_manager_get_task_handler($handler->handler); + + if (user_access('administer page manager') && isset($handler->task)) { + // Provide a tab to edit this context: + ctools_include('menu'); + $task = page_manager_get_task($handler->task); + + $title = !empty($task['tab title']) ? $task['tab title'] : t('Edit @type', array('@type' => $plugin['title'])); + $trail = array(); + if (!empty($plugin['tab operation'])) { + if (is_array($plugin['tab operation'])) { + $trail = $plugin['tab operation']; + } + else if (function_exists($plugin['tab operation'])) { + $trail = $plugin['tab operation']($handler, $contexts, $args); + } + } + + ctools_menu_add_tab(array( + 'title' => $title, + 'href' => page_manager_edit_url(page_manager_make_task_name($handler->task, $handler->subtask), $trail), + )); + } +} + +/** + * Compare arguments to contexts for selection purposes. + * + * @param $handler + * The handler in question. + * @param $contexts + * The context objects provided by the task. + * + * @return + * TRUE if these contexts match the selection rules. NULL or FALSE + * otherwise. + */ +function ctools_context_handler_select($handler, $contexts) { + if (empty($handler->conf['access'])) { + return TRUE; + } + + ctools_include('context'); + return ctools_access($handler->conf['access'], $contexts); +} + +/** + * Get the array of summary strings for the arguments. + * + * These summary strings are used to communicate to the user what + * arguments the task handlers are selecting. + * + * @param $task + * The loaded task plugin. + * @param $subtask + * The subtask id. + * @param $handler + * The handler to be checked. + */ +function ctools_context_handler_summary($task, $subtask, $handler) { + if (empty($handler->conf['access']['plugins'])) { + return array(); + } + + ctools_include('context'); + $strings = array(); + $contexts = ctools_context_handler_get_all_contexts($task, $subtask, $handler); + + foreach ($handler->conf['access']['plugins'] as $test) { + $plugin = ctools_get_access_plugin($test['name']); + if ($string = ctools_access_summary($plugin, $contexts, $test)) { + $strings[] = $string; + } + } + + return $strings; +} + +// -------------------------------------------------------------------------- +// Tasks and Task handlers can both have their own sources of contexts. +// Sometimes we need all of these contexts at once (when editing +// the task handler, for example) but sometimes we need them separately +// (when a task has contexts loaded and is trying out the task handlers, +// for example). Therefore there are two paths we can take to getting contexts. + +/** + * Load the contexts for a task, using arguments. + * + * This creates the base array of contexts, loaded from arguments, suitable + * for use in rendering. + */ +function ctools_context_handler_get_task_contexts($task, $subtask, $args) { + $contexts = ctools_context_handler_get_base_contexts($task, $subtask); + $arguments = ctools_context_handler_get_task_arguments($task, $subtask); + ctools_context_get_context_from_arguments($arguments, $contexts, $args); + + return $contexts; +} + +/** + * Load the contexts for a task handler. + * + * This expands a base set of contexts passed in from a task with the + * contexts defined on the task handler. The contexts from the task + * must already have been loaded. + */ +function ctools_context_handler_get_handler_contexts($contexts, $handler) { + $object = ctools_context_handler_get_handler_object($handler); + return ctools_context_load_contexts($object, FALSE, $contexts); +} + +/** + * Load the contexts for a task and task handler together. + * + * This pulls the arguments from a task and everything else from a task + * handler and loads them as a group. Since there is no data, this loads + * the contexts as placeholders. + */ +function ctools_context_handler_get_all_contexts($task, $subtask, $handler) { + $contexts = array(); + + $object = ctools_context_handler_get_task_object($task, $subtask, $handler); + $contexts = ctools_context_load_contexts($object, TRUE, $contexts); + ctools_context_handler_set_access_restrictions($task, $subtask, $handler, $contexts); + return $contexts; +} + +/** + * Create an object suitable for use with the context system that kind of + * expects things in a certain, kind of clunky format. + */ +function ctools_context_handler_get_handler_object($handler) { + $object = new stdClass; + $object->name = $handler->name; + $object->contexts = isset($handler->conf['contexts']) ? $handler->conf['contexts'] : array(); + $object->relationships = isset($handler->conf['relationships']) ? $handler->conf['relationships'] : array(); + + return $object; +} + +/** + * Create an object suitable for use with the context system that kind of + * expects things in a certain, kind of clunky format. This one adds in + * arguments from the task. + */ +function ctools_context_handler_get_task_object($task, $subtask, $handler) { + $object = new stdClass; + $object->name = !empty($handler->name) ? $handler->name : 'temp'; + $object->base_contexts = ctools_context_handler_get_base_contexts($task, $subtask, TRUE); + $object->arguments = ctools_context_handler_get_task_arguments($task, $subtask); + $object->contexts = isset($handler->conf['contexts']) ? $handler->conf['contexts'] : array(); + $object->relationships = isset($handler->conf['relationships']) ? $handler->conf['relationships'] : array(); + + return $object; +} + +/** + * Get base contexts from a task, if it has any. + * + * Tasks can get their contexts either from base contexts or arguments; base + * contexts extract their information from the environment. + */ +function ctools_context_handler_get_base_contexts($task, $subtask, $placeholders = FALSE) { + if ($function = ctools_plugin_get_function($task, 'get base contexts')) { + return $function($task, $subtask, $placeholders); + } + + return array(); +} + +/** + * Get the arguments from a task that are used to load contexts. + */ +function ctools_context_handler_get_task_arguments($task, $subtask) { + if ($function = ctools_plugin_get_function($task, 'get arguments')) { + return $function($task, $subtask); + } + + return array(); +} + +/** + * Set any access restrictions on the contexts for a handler. + * + * Both the task and the handler could add restrictions to the contexts + * based upon the access control. These restrictions might be useful + * to limit what kind of content appears in the add content dialog; + * for example, if we have an access item that limits a node context + * to only 'story' and 'page' types, there is no need for content that + * only applies to the 'poll' type to appear. + */ +function ctools_context_handler_set_access_restrictions($task, $subtask, $handler, &$contexts) { + // First, for the task: + if ($function = ctools_plugin_get_function($task, 'access restrictions')) { + $function($task, $subtask, $contexts); + } + + // Then for the handler: + if (isset($handler->conf['access'])) { + ctools_access_add_restrictions($handler->conf['access'], $contexts); + } +} + +/** + * Form to choose context based selection rules for a task handler. + * + * The configuration will be assumed to go simply in $handler->conf and + * will be keyed by the argument ID. + */ +function ctools_context_handler_edit_criteria(&$form, &$form_state) { + if (!isset($form_state['handler']->conf['access'])) { + $form_state['handler']->conf['access'] = array(); + } + + ctools_include('context'); + ctools_include('modal'); + ctools_include('ajax'); + ctools_modal_add_plugin_js(ctools_get_access_plugins()); + ctools_include('context-access-admin'); + $form_state['module'] = 'page_manager_task_handler'; + // Encode a bunch of info into the argument so we can get our cache later + $form_state['callback argument'] = $form_state['task_name'] . '*' . $form_state['handler']->name; + $form_state['access'] = $form_state['handler']->conf['access']; + $form_state['no buttons'] = TRUE; + $form_state['contexts'] = ctools_context_handler_get_all_contexts($form_state['task'], $form_state['subtask'], $form_state['handler']); + + $form['markup'] = array( + '#value' => '<div class="description">' . + t('If there is more than one variant on a page, when the page is visited each variant is given an opportunity to be displayed. Starting from the first variant and working to the last, each one tests to see if its selection rules will pass. The first variant that its criteria (as specified below) will be used.') . + '</div>', + ); + $form = array_merge($form, ctools_access_admin_form($form_state)); +} + +/** + * Submit handler for rules selection + */ +function ctools_context_handler_edit_criteria_submit(&$form, &$form_state) { + $form_state['handler']->conf['access']['logic'] = $form_state['values']['logic']; +} + +/** + * Edit contexts that go with this panel. + */ +function ctools_context_handler_edit_context(&$form, &$form_state) { + ctools_include('context-admin'); + ctools_context_admin_includes(); + + $handler = $form_state['handler']; + $page = $form_state['page']; + $cache_name = $handler->name ? $handler->name : 'temp'; + if (isset($page->context_cache[$cache_name])) { + $cache = $page->context_cache[$cache_name]; + } + else { + $cache = ctools_context_handler_get_task_object($form_state['task'], $form_state['subtask'], $form_state['handler']); + $form_state['page']->context_cache[$cache_name] = $cache; + } + + $form['right'] = array( + '#prefix' => '<div class="clear-block"><div class="right-container">', + '#suffix' => '</div>', + ); + + $form['left'] = array( + '#prefix' => '<div class="left-container">', + '#suffix' => '</div></div>', + ); + + $module = 'page_manager-' . $page->task_name; + ctools_context_add_context_form($module, $form, $form_state, $form['right']['contexts_table'], $cache); + ctools_context_add_relationship_form($module, $form, $form_state, $form['right']['relationships_table'], $cache); + + // Set an additional description if CCK and Token are enabled, to notify of unlisted keywords + if (module_exists('content') && module_exists('token')) { + $description = t('Note that CCK fields may be used as keywords using patterns like <em>%node:field_name-formatted</em>.'); + } elseif (!module_exists('token')) { + $description = t('More keywords will be available if you install the Token module, see http://drupal.org/project/token.'); + } + + $form['left']['summary'] = array( + '#prefix' => '<div class="page-manager-contexts">', + '#suffix' => '</div>', + '#value' => theme('ctools_context_list', $cache, t('Summary of contexts'), $description), + ); + + $form_state['context_object'] = &$cache; +} + +/** + * Process submission of the context edit form. + */ +function ctools_context_handler_edit_context_submit(&$form, &$form_state) { + $handler = &$form_state['handler']; + + $cache_name = $handler->name ? $handler->name : 'temp'; + + $handler->conf['contexts'] = $form_state['context_object']->contexts; + $handler->conf['relationships'] = $form_state['context_object']->relationships; + if (isset($form_state['page']->context_cache[$cache_name])) { + unset($form_state['page']->context_cache[$cache_name]); + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.inc new file mode 100644 index 0000000000000000000000000000000000000000..47735c490458c5a84f75d940b741d43f5f9f3f82 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.inc @@ -0,0 +1,1537 @@ +<?php + +/** + * @file + * + * Contains code related to the ctools system of 'context'. + * + * Context, originally from Panels, is a method of packaging objects into + * a more generic bundle and providing a plugin system so that a UI can + * take advantage of them. The idea is that the context objects + * represent 'the context' that a given operation (usually a page view) + * is operating in or on. + * + * For example, when viewing a page, the 'context' is a node object. When + * viewing a user, the 'context' is a user object. Contexs can also + * have related contexts. For example, when viewing a 'node' you may need + * to know something about the node author. Therefore, the node author + * is a related context. + */ + +/** + * The context object is largely a wrapper around some other object, with + * an interface to finding out what is contained and getting to both + * the object and information about the object. + * + * Each context object has its own information, but some things are very + * common, such as titles, data, keywords, etc. In particulare, the 'type' + * of the context is important. + */ +class ctools_context { + var $type = NULL; + var $data = NULL; + // The title of this object. + var $title = ''; + // The title of the page if this object exists + var $page_title = ''; + // The identifier (in the UI) of this object + var $identifier = ''; + var $argument = NULL; + var $keyword = ''; + var $original_argument = NULL; + var $restrictions = array(); + var $empty = FALSE; + + function ctools_context($type = 'none', $data = NULL) { + $this->type = $type; + $this->data = $data; + $this->title = t('Unknown context'); + } + + function is_type($type) { + if ($type == 'any' || $this->type == 'any') { + return TRUE; + } + + $a = is_array($type) ? $type : array($type); + $b = is_array($this->type) ? $this->type : array($this->type); + return (bool) array_intersect($a, $b); + } + + function get_argument() { + return $this->argument; + } + + function get_original_argument() { + if (!is_null($this->original_argument)) { + return $this->original_argument; + } + return $this->argument; + } + + function get_keyword() { + return $this->keyword; + } + + function get_identifier() { + return $this->identifier; + } + + function get_title() { + return $this->title; + } + + function get_page_title() { + return $this->page_title; + } +} + +/** + * Used to create a method of comparing if a list of contexts + * match a required context type. + */ +class ctools_context_required { + var $keywords = ''; + + /** + * If set, the title will be used in the selector to identify + * the context. This is very useful when multiple contexts + * are required to inform the user will be used for what. + */ + var $title = NULL; + + /** + * Test to see if this context is required. + */ + var $required = TRUE; + + /** + * + * @param $title + * The first parameter should be the 'title' of the context for use + * in UYI selectors when multiple contexts qualify. + * @param ... + * One or more keywords to use for matching which contexts are allowed. + */ + function ctools_context_required($title) { + $args = func_get_args(); + $this->title = array_shift($args); + + // If we were given restrictions at the end, store them. + if (count($args) > 1 && is_array(end($args))) { + $this->restrictions = array_pop($args); + } + + if (count($args) == 1) { + $args = array_shift($args); + } + $this->keywords = $args; + } + + function filter($contexts) { + $result = array(); + + // See which of these contexts are valid + foreach ((array) $contexts as $cid => $context) { + if ($context->is_type($this->keywords)) { + // Compare to see if our contexts were met. + if (!empty($this->restrictions) && !empty($context->restrictions)) { + foreach ($this->restrictions as $key => $values) { + // If we have a restriction, the context must either not have that + // restriction listed, which means we simply don't know what it is, + // or there must be an intersection of the restricted values on + // both sides. + if (!is_array($values)) { + $values = array($values); + } + if (!empty($context->restrictions[$key]) && !array_intersect($values, $context->restrictions[$key])) { + continue 2; + } + } + } + $result[$cid] = $context; + } + } + + return $result; + } + + function select($contexts, $context) { + if (!is_array($contexts)) { + $contexts = array($contexts); + } + + // Due to a bug, some contexts got recorded with an id of 0. This will + // convert them to the correct ID allowing for some earlier panels + // to continue to work. + if (!empty($context) && $context[strlen($context) - 1] === '0') { + $context[strlen($context) - 1] = 1; + } + + if (empty($context) || empty($contexts[$context])) { + return FALSE; + } + return $contexts[$context]; + } +} + +/** + * Used to compare to see if a list of contexts match an optional context. This + * can produce empty contexts to use as placeholders. + */ +class ctools_context_optional extends ctools_context_required { + var $required = FALSE; + function ctools_context_optional() { + $args = func_get_args(); + call_user_func_array(array($this, 'ctools_context_required'), $args); + } + + /** + * Add the 'empty' context which is possible for optional + */ + function add_empty(&$contexts) { + $context = new ctools_context('any'); + $context->title = t('No context'); + $context->identifier = t('No context'); + $contexts = array_merge(array('empty' => $context), $contexts); + } + + function filter($contexts) { + $this->add_empty($contexts); + return parent::filter($contexts); + } + + function select($contexts, $context) { + $this->add_empty($contexts); + if (empty($context)) { + return $contexts['empty']; + } + + $result = parent::select($contexts, $context); + + // Don't flip out if it can't find the context; this is optional, put + // in an empty. + if ($result == FALSE) { + $result = $contexts['empty']; + } + return $result; + } +} + +/** + * Return a keyed array of context that match the given 'required context' + * filters. + * + * Functions or systems that require contexts of a particular type provide a + * ctools_context_required or ctools_context_optional object. This function + * examines that object and an array of contexts to determine which contexts + * match the filter. + * + * Since multiple contexts can be required, this function will accept either + * an array of all required contexts, or just a single required context object. + * + * @param $contexts + * A keyed array of all available contexts. + * @param $required + * A ctools_context_required or ctools_context_optional object, or an array + * of such objects. + * + * @return + * A keyed array of contexts that match the filter. + */ +function ctools_context_filter($contexts, $required) { + if (is_array($required)) { + $result = array(); + foreach ($required as $r) { + $result = array_merge($result, _ctools_context_filter($contexts, $r)); + } + return $result; + } + + return _ctools_context_filter($contexts, $required); +} + +function _ctools_context_filter($contexts, $required) { + $result = array(); + + if (is_object($required)) { + $result = $required->filter($contexts); + } + + return $result; +} + +/** + * Create a select box to choose possible contexts. + * + * This only creates a selector if there is actually a choice; if there + * is only one possible context, that one is silently assigned. + * + * If an array of required contexts is provided, one selector will be + * provided for each context. + * + * @param $contexts + * A keyed array of all available contexts. + * @param $required + * The required context object or array of objects. + * + * @return + * A form element, or NULL if there are no contexts that satisfy the + * requirements. + */ +function ctools_context_selector($contexts, $required, $default) { + if (is_array($required)) { + $result = array('#tree' => TRUE); + $count = 1; + foreach ($required as $id => $r) { + $result[] = _ctools_context_selector($contexts, $r, isset($default[$id]) ? $default[$id] : '', $count++); + } + return $result; + } + + return _ctools_context_selector($contexts, $required, $default); +} + +function _ctools_context_selector($contexts, $required, $default, $num = 0) { + $filtered = ctools_context_filter($contexts, $required); + $count = count($filtered); + + $form = array(); + + if ($count >= 1) { + // If there's more than one to choose from, create a select widget. + foreach ($filtered as $cid => $context) { + $options[$cid] = $context->get_identifier(); + } + if (!empty($required->title)) { + $title = $required->title; + } + else { + $title = $num ? t('Context %count', array('%count' => $num)) : t('Context'); + } + + return array( + '#type' => 'select', + '#options' => $options, + '#title' => $title, + '#default_value' => $default, + ); + } +} + +/** + * Are there enough contexts for a plugin? + * + * Some plugins can have a 'required contexts' item which can either + * be a context requirement object or an array of them. When contexts + * are required, items that do not have enough contexts should not + * appear. This tests an item to see if it has enough contexts + * to actually appear. + * + * @param $contexts + * A keyed array of all available contexts. + * @param $required + * The required context object or array of objects. + * + * @return + * TRUE if there are enough contexts, FALSE if there are not. + */ +function ctools_context_match_requirements($contexts, $required) { + if (!is_array($required)) { + $required = array($required); + } + + // Get the keys to avoid bugs in PHP 5.0.8 with keys and loops. + // And use it to remove optional contexts. + $keys = array_keys($required); + foreach ($keys as $key) { + if (empty($required[$key]->required)) { + unset($required[$key]); + } + } + + $count = count($required); + return (count(ctools_context_filter($contexts, $required)) >= $count); +} + +/** + * Create a select box to choose possible contexts. + * + * This only creates a selector if there is actually a choice; if there + * is only one possible context, that one is silently assigned. + * + * If an array of required contexts is provided, one selector will be + * provided for each context. + * + * @param $contexts + * A keyed array of all available contexts. + * @param $required + * The required context object or array of objects. + * + * @return + * A form element, or NULL if there are no contexts that satisfy the + * requirements. + */ +function ctools_context_converter_selector($contexts, $required, $default) { + if (is_array($required)) { + $result = array('#tree' => TRUE); + $count = 1; + foreach ($required as $id => $r) { + $result[] = _ctools_context_converter_selector($contexts, $r, isset($default[$id]) ? $default[$id] : '', $count++); + } + return $result; + } + + return _ctools_context_converter_selector($contexts, $required, $default); +} + +function _ctools_context_converter_selector($contexts, $required, $default, $num = 0) { + $filtered = ctools_context_filter($contexts, $required); + $count = count($filtered); + + $form = array(); + + if ($count > 1) { + // If there's more than one to choose from, create a select widget. + $options = array(); + foreach ($filtered as $cid => $context) { + if ($context->type == 'any') { + $options[''] = t('No context'); + continue; + } + $key = $context->get_identifier(); + if ($converters = ctools_context_get_converters($cid . '.', $context)) { + $options[$key] = $converters; + } + } + if (empty($options)) { + return array( + '#type' => 'value', + '#value' => 'any', + ); + } + if (!empty($required->title)) { + $title = $required->title; + } + else { + $title = $num ? t('Context %count', array('%count' => $num)) : t('Context'); + } + + return array( + '#type' => 'select', + '#options' => $options, + '#title' => $title, + '#description' => t('Please choose which context and how you would like it converted.'), + '#default_value' => $default, + ); + } +} + +/** + * Get a list of converters available for a given context. + */ +function ctools_context_get_converters($cid, $context) { + if (empty($context->plugin)) { + return array(); + } + + return _ctools_context_get_converters($cid, $context->plugin); +} + +/** + * Get a list of converters available for a given context. + */ +function _ctools_context_get_converters($id, $plugin_name) { + $plugin = ctools_get_context($plugin_name); + if (empty($plugin['convert list'])) { + return array(); + } + + $converters = array(); + if (is_array($plugin['convert list'])) { + $converters = $plugin['convert list']; + } + else if ($function = ctools_plugin_get_function($plugin, 'convert list')) { + $converters = (array) $function(); + } + + // DEPRECATED, but left in: This alter was misnamed. + foreach (module_implements('ctools_context_convert_list') as $module) { + $function = $module . '_ctools_context_convert_list'; + $function($plugin, $converters); + } + + foreach (module_implements('ctools_context_convert_list_alter') as $module) { + $function = $module . '_ctools_context_convert_list_alter'; + $function($plugin, $converters); + } + + // Now, change them all to include the plugin: + $return = array(); + foreach ($converters as $key => $title) { + $return[$id . $key] = $title; + } + + natcasesort($return); + return $return; +} + +/** + * Get a list of all contexts + converters available. + */ +function ctools_context_get_all_converters() { + $contexts = ctools_get_contexts(); + $converters = array(); + foreach ($contexts as $name => $context) { + $context_converters = _ctools_context_get_converters($name . '.', $name); + if ($context_converters) { + $converters[$context['title']] = $context_converters; + } + } + + return $converters; +} + +/** + * Let the context convert an argument based upon the converter that was given. + */ +function ctools_context_convert_context($context, $converter) { + $value = $context->argument; + if ($function = ctools_plugin_load_function('ctools', 'contexts', $context->plugin, 'convert')) { + $value = $function($context, $converter); + } + + foreach (module_implements('ctools_context_converter_alter') as $module) { + $function = $module . '_ctools_context_converter_alter'; + $function($context, $converter, $value); + } + + return $value; +} + +/** + * Choose a context or contexts based upon the selection made via + * ctools_context_filter. + * + * @param $contexts + * A keyed array of all available contexts + * @param $required + * The required context object provided by the plugin + * @param $context + * The selection made using ctools_context_selector + */ +function ctools_context_select($contexts, $required, $context) { + if (is_array($required)) { + $result = array(); + foreach ($required as $id => $r) { + if (($result[] = _ctools_context_select($contexts, $r, $context[$id])) === FALSE) { + return FALSE; + } + } + return $result; + } + + return _ctools_context_select($contexts, $required, $context); +} + +function _ctools_context_select($contexts, $required, $context) { + if (!is_object($required)) { + return FALSE; + } + + return $required->select($contexts, $context); +} + +/** + * Create a new context object. + * + * @param $type + * The type of context to create; this loads a plugin. + * @param $data + * The data to put into the context. + * @param $empty + * Whether or not this context is specifically empty. + * @param $conf + * A configuration structure if this context was created via UI. + * + * @return + * A $context or NULL if one could not be created. + */ +function ctools_context_create($type, $data = NULL, $conf = FALSE) { + ctools_include('plugins'); + if ($function = ctools_plugin_load_function('ctools', 'contexts', $type, 'context')) { + return $function(FALSE, $data, $conf); + } +} + +/** + * Create an empty context object. + * + * Empty context objects are primarily used as placeholders in the UI where + * the actual contents of a context object may not be known. It may have + * additional text embedded to give the user clues as to how the context + * is used. + * + * @param $type + * The type of context to create; this loads a plugin. + * + * @return + * A $context or NULL if one could not be created. + */ +function ctools_context_create_empty($type) { + if ($function = ctools_plugin_load_function('ctools', 'contexts', $type, 'context')) { + $context = $function(TRUE); + if (is_object($context)) { + $context->empty = TRUE; + } + + return $context; + } +} + +/** + * Perform keyword and context substitutions. + */ +function ctools_context_keyword_substitute($string, $keywords, $contexts) { + // Ensure a default keyword exists: + $keywords['%%'] = '%'; + + // Match contexts to the base keywords: + $context_keywords = array(); + foreach ($contexts as $context) { + if (isset($context->keyword)) { + $context_keywords[$context->keyword] = $context; + } + } + + // Look for context matches we we only have to convert known matches. + $matches = array(); + if (preg_match_all('/%([a-zA-Z0-9%:_-]+)/us', $string, $matches)) { + foreach ($matches[1] as $keyword) { + // Ignore anything it finds with %%. + if ($keyword[0] == '%') { + continue; + } + + // If the keyword is already set by something passed in, don't try to + // overwrite it. + if (!empty($keywords['%' . $keyword])) { + continue; + } + + // Figure out our keyword and converter, if specified. + if (strpos($keyword, ':')) { + list($context, $converter) = explode(':', $keyword, 2); + } + else { + $context = $keyword; + if (isset($context_keywords[$keyword])) { + $plugin = ctools_get_context($context_keywords[$context]->plugin); + + // Fall back to a default converter, if specified. + if ($plugin && !empty($plugin['convert default'])) { + $converter = $plugin['convert default']; + } + } + } + + if (empty($context_keywords[$context]) || !empty($context_keywords[$context]->empty)) { + $keywords['%' . $keyword] = ''; + } + else if (!empty($converter)) { + $keywords['%' . $keyword] = ctools_context_convert_context($context_keywords[$context], $converter); + } + else { + $keywords['%' . $keyword] = $context_keywords[$keyword]->title; + } + } + } + return strtr($string, $keywords); +} + +/** + * Determine a unique context ID for a context + * + * Often contexts of many different types will be placed into a list. This + * ensures that even though contexts of multiple types may share IDs, they + * are unique in the final list. + */ +function ctools_context_id($context, $type = 'context') { + if (!$context['id']) { + $context['id'] = 1; + } + + return $type . '_' . $context['name'] . '_' . $context['id']; +} + +/** + * Get the next id available given a list of already existing objects. + * + * This finds the next id available for the named object. + * + * @param $objects + * A list of context descriptor objects, i.e, arguments, relationships, contexts, etc. + * @param $name + * The name being used. + */ +function ctools_context_next_id($objects, $name) { + $id = 0; + // Figure out which instance of this argument we're creating + if (!$objects) { + return $id + 1; + } + + foreach ($objects as $object) { + if (isset($object['name']) && $object['name'] == $name) { + if ($object['id'] > $id) { + $id = $object['id']; + } + } + } + + return $id + 1; +} + + +// --------------------------------------------------------------------------- +// Functions related to contexts from arguments. + +/** + * Fetch metadata on a specific argument plugin. + * + * @param $argument + * Name of an argument plugin. + * + * @return + * An array with information about the requested argument plugin. + */ +function ctools_get_argument($argument) { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'arguments', $argument); +} + +/** + * Fetch metadata for all argument plugins. + * + * @return + * An array of arrays with information about all available argument plugins. + */ +function ctools_get_arguments() { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'arguments'); +} + +/** + * Get a context from an argument. + * + * @param $argument + * The configuration of an argument. It must contain the following data: + * - name: The name of the argument plugin being used. + * - argument_settings: The configuration based upon the plugin forms. + * - identifier: The human readable identifier for this argument, usually + * defined by the UI. + * - keyword: The keyword used for this argument for substitutions. + * + * @param $arg + * The actual argument received. This is expected to be a string from a URL but + * this does not have to be the only source of arguments. + * @param $empty + * If true, the $arg will not be used to load the context. Instead, an empty + * placeholder context will be loaded. + * + * @return + * A context object if one can be loaded. + */ +function ctools_context_get_context_from_argument($argument, $arg, $empty = FALSE) { + ctools_include('plugins'); + if (empty($argument['name'])) { + return; + } + + if ($function = ctools_plugin_load_function('ctools', 'arguments', $argument['name'], 'context')) { + if (!isset($argument['settings'])) { + $argument['settings'] = array(); + } + + $context = $function($arg, $argument['settings'], $empty); + + if (is_object($context)) { + $context->identifier = $argument['identifier']; + $context->page_title = isset($argument['title']) ? $argument['title'] : ''; + $context->keyword = $argument['keyword']; + $context->id = ctools_context_id($argument, 'argument'); + $context->original_argument = $arg; + + if (!empty($context->empty)) { + $context->placeholder = array( + 'type' => 'argument', + 'conf' => $argument, + ); + } + } + return $context; + } +} + +/** + * Retrieve a list of empty contexts for all arguments. + */ +function ctools_context_get_placeholders_from_argument($arguments) { + $contexts = array(); + foreach ($arguments as $argument) { + $context = ctools_context_get_context_from_argument($argument, NULL, TRUE); + if ($context) { + $contexts[ctools_context_id($argument, 'argument')] = $context; + } + } + return $contexts; +} + +/** + * Load the contexts for a given list of arguments. + * + * @param $arguments + * The array of argument definitions. + * @param &$contexts + * The array of existing contexts. New contexts will be added to this array. + * @param $args + * The arguments to load. + * + * @return + * FALSE if an argument wants to 404. + */ +function ctools_context_get_context_from_arguments($arguments, &$contexts, $args) { + foreach ($arguments as $argument) { + // pull the argument off the list. + $arg = array_shift($args); + $id = ctools_context_id($argument, 'argument'); + + // For % arguments embedded in the URL, our context is already loaded. + // There is no need to go and load it again. + if (empty($contexts[$id])) { + if ($context = ctools_context_get_context_from_argument($argument, $arg)) { + $contexts[$id] = $context; + } + } + else { + $context = $contexts[$id]; + } + + if ((empty($context) || empty($context->data)) && !empty($argument['default']) && $argument['default'] == '404') { + return FALSE; + } + } + return TRUE; +} + +// --------------------------------------------------------------------------- +// Functions related to contexts from relationships. + +/** + * Fetch metadata on a specific relationship plugin. + * + * @param $content type + * Name of a panel content type. + * + * @return + * An array with information about the requested relationship. + */ +function ctools_get_relationship($relationship) { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'relationships', $relationship); +} + +/** + * Fetch metadata for all relationship plugins. + * + * @return + * An array of arrays with information about all available relationships. + */ +function ctools_get_relationships() { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'relationships'); +} + +/** + * + * @param $relationship + * The configuration of a relationship. It must contain the following data: + * - name: The name of the relationship plugin being used. + * - relationship_settings: The configuration based upon the plugin forms. + * - identifier: The human readable identifier for this relationship, usually + * defined by the UI. + * - keyword: The keyword used for this relationship for substitutions. + * + * @param $source_context + * The context this relationship is based upon. + * + * @param $placeholders + * If TRUE, placeholders are acceptable. + * + * @return + * A context object if one can be loaded. + */ +function ctools_context_get_context_from_relationship($relationship, $source_context, $placeholders = FALSE) { + ctools_include('plugins'); + if ($function = ctools_plugin_load_function('ctools', 'relationships', $relationship['name'], 'context')) { + if (!isset($relationship['relationship_settings'])) { + $relationship['relationship_settings'] = array(); + } + + $context = $function($source_context, $relationship['relationship_settings'], $placeholders); + if ($context) { + $context->identifier = $relationship['identifier']; + $context->page_title = isset($relationship['title']) ? $relationship['title'] : ''; + $context->keyword = $relationship['keyword']; + if (!empty($context->empty)) { + $context->placeholder = array( + 'type' => 'relationship', + 'conf' => $relationship, + ); + } + return $context; + } + } +} + +/** + * Fetch all relevant relationships. + * + * Relevant relationships are any relationship that can be created based upon + * the list of existing contexts. For example, the 'node author' relationship + * is relevant if there is a 'node' context, but makes no sense if there is + * not one. + * + * @param $contexts + * An array of contexts used to figure out which relationships are relevant. + * + * @return + * An array of relationship keys that are relevant for the given set of + * contexts. + */ +function ctools_context_get_relevant_relationships($contexts) { + $relevant = array(); + $relationships = ctools_get_relationships(); + + // Go through each relationship + foreach ($relationships as $rid => $relationship) { + // For each relationship, see if there is a context that satisfies it. + if (ctools_context_filter($contexts, $relationship['required context'])) { + $relevant[$rid] = $relationship['title']; + } + } + + return $relevant; +} + +/** + * Fetch all active relationships + * + * @param $relationships + * An keyed array of relationship data including: + * - name: name of relationship + * - context: context id relationship belongs to. This will be used to + * identify which context in the $contexts array to use to create the + * relationship context. + * + * @param $contexts + * A keyed array of contexts used to figure out which relationships + * are relevant. New contexts will be added to this. + * + * @param $placeholders + * If TRUE, placeholders are acceptable. + */ +function ctools_context_get_context_from_relationships($relationships, &$contexts, $placeholders = FALSE) { + $return = array(); + + foreach ($relationships as $rdata) { + if (!isset($rdata['context'])) { + continue; + } + + if (is_array($rdata['context'])) { + $rcontexts = array(); + foreach ($rdata['context'] as $cid) { + if (empty($contexts[$cid])) { + continue 2; + } + $rcontexts[] = $contexts[$cid]; + } + } + else { + if (empty($contexts[$rdata['context']])) { + continue; + } + $rcontexts = $contexts[$rdata['context']]; + } + + $cid = ctools_context_id($rdata, 'relationship'); + if ($context = ctools_context_get_context_from_relationship($rdata, $rcontexts)) { + $contexts[$cid] = $context; + } + } +} + +// --------------------------------------------------------------------------- +// Functions related to loading contexts from simple context definitions. + +/** + * Fetch metadata on a specific context plugin. + * + * @param $context + * Name of a context. + * + * @return + * An array with information about the requested panel context. + */ +function ctools_get_context($context) { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'contexts', $context); +} + +/** + * Fetch metadata for all context plugins. + * + * @return + * An array of arrays with information about all available panel contexts. + */ +function ctools_get_contexts() { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'contexts'); +} + +/** + * + * @param $context + * The configuration of a context. It must contain the following data: + * - name: The name of the context plugin being used. + * - context_settings: The configuration based upon the plugin forms. + * - identifier: The human readable identifier for this context, usually + * defined by the UI. + * - keyword: The keyword used for this context for substitutions. + * @param $type + * This is either 'context' which indicates the context will be loaded + * from data in the settings, or 'required_context' which means the + * context must be acquired from an external source. This is the method + * used to pass pure contexts from one system to another. + * + * @return + * A context object if one can be loaded. + */ +function ctools_context_get_context_from_context($context, $type = 'context', $argument = NULL) { + ctools_include('plugins'); + $plugin = ctools_get_context($context['name']); + if ($function = ctools_plugin_get_function($plugin, 'context')) { + if (!isset($context['context_settings'])) { + $context['context_settings'] = array(); + } + + if (isset($argument) && isset($plugin['placeholder name'])) { + $context['context_settings'][$plugin['placeholder name']] = $argument; + } + + $return = $function($type == 'requiredcontext', $context['context_settings'], TRUE); + if ($return) { + $return->identifier = $context['identifier']; + $return->page_title = isset($context['title']) ? $context['title'] : ''; + $return->keyword = $context['keyword']; + + if (!empty($context->empty)) { + $context->placeholder = array( + 'type' => 'context', + 'conf' => $context, + ); + } + + return $return; + } + } +} + +/** + * Retrieve a list of base contexts based upon a simple 'contexts' definition. + * + * For required contexts this will always retrieve placeholders. + * + * @param $contexts + * The list of contexts defined in the UI. + * @param $type + * Either 'context' or 'requiredcontext', which indicates whether the contexts + * are loaded from internal data or copied from an external source. + * @param $placeholders + * If true, placeholders are acceptable. + */ +function ctools_context_get_context_from_contexts($contexts, $type = 'context', $placeholders = FALSE) { + $return = array(); + foreach ($contexts as $context) { + $ctext = ctools_context_get_context_from_context($context, $type); + if ($ctext) { + if ($placeholders) { + $ctext->placeholder = TRUE; + } + $return[ctools_context_id($context, $type)] = $ctext; + } + } + return $return; +} + +/** + * Match up external contexts to our required contexts. + * + * This function is used to create a list of contexts with proper + * IDs based upon a list of required contexts. + * + * These contexts passed in should match the numeric positions of the + * required contexts. The caller must ensure this has already happened + * correctly as this function will not detect errors here. + * + * @param $required + * A list of required contexts as defined by the UI. + * @param $contexts + * A list of matching contexts as passed in from the calling system. + */ +function ctools_context_match_required_contexts($required, $contexts) { + $return = array(); + if (!is_array($required)) { + return $return; + } + + foreach ($required as $r) { + $context = drupal_clone(array_shift($contexts)); + $context->identifier = $r['identifier']; + $context->page_title = isset($r['title']) ? $r['title'] : ''; + $context->keyword = $r['keyword']; + $return[ctools_context_id($r, 'requiredcontext')] = $context; + } + + return $return; +} + +/** + * Load a full array of contexts for an object. + * + * Not all of the types need to be supported by this object. + * + * This function is not used to load contexts from external data, but may + * be used to load internal contexts and relationships. Otherwise it can also + * be used to generate a full set of placeholders for UI purposes. + * + * @param $object + * An object that contains some or all of the following variables: + * + * - requiredcontexts: A list of UI configured contexts that are required + * from an external source. Since these require external data, they will + * only be added if $placeholders is set to TRUE, and empty contexts will + * be created. + * - arguments: A list of UI configured arguments that will create contexts. + * Since these require external data, they will only be added if $placeholders + * is set to TRUE. + * - contexts: A list of UI configured contexts that have no external source, + * and are essentially hardcoded. For example, these might configure a + * particular node or a particular taxonomy term. + * - relationships: A list of UI configured contexts to be derived from other + * contexts that already exist from other sources. For example, these might + * be used to get a user object from a node via the node author relationship. + * @param $placeholders + * If TRUE, this will generate placeholder objects for types this function + * cannot load. + * @param $contexts + * An array of pre-existing contexts that will be part of the return value. + */ +function ctools_context_load_contexts($object, $placeholders = TRUE, $contexts = array()) { + if (!empty($object->base_contexts)) { + $contexts += $object->base_contexts; + } + + if ($placeholders) { + // This will load empty contexts as placeholders for arguments that come + // from external sources. If this isn't set, it's assumed these context + // will already have been matched up and loaded. + if (!empty($object->requiredcontexts) && is_array($object->requiredcontexts)) { + $contexts += ctools_context_get_context_from_contexts($object->requiredcontexts, 'requiredcontext', $placeholders); + } + + if (!empty($object->arguments) && is_array($object->arguments)) { + $contexts += ctools_context_get_placeholders_from_argument($object->arguments); + } + } + + if (!empty($object->contexts) && is_array($object->contexts)) { + $contexts += ctools_context_get_context_from_contexts($object->contexts, 'context', $placeholders); + } + + // add contexts from relationships + if (!empty($object->relationships) && is_array($object->relationships)) { + ctools_context_get_context_from_relationships($object->relationships, $contexts, $placeholders); + } + + return $contexts; +} + +/** + * Return the first context with a form id from a list of contexts. + * + * This function is used to figure out which contexts represents 'the form' + * from a list of contexts. Only one contexts can actually be 'the form' for + * a given page, since the @code{<form>} tag can not be embedded within + * itself. + */ +function ctools_context_get_form($contexts) { + if (!empty($contexts)) { + foreach ($contexts as $id => $context) { + // if a form shows its id as being a 'required context' that means the + // the context is external to this display and does not count. + if (!empty($context->form_id) && substr($id, 0, 15) != 'requiredcontext') { + return $context; + } + } + } +} + +/** + * Replace placeholders with real contexts using data extracted from a form + * for the purposes of previews. + * + * @param $contexts + * All of the contexts, including the placeholders. + * @param $arguments + * The arguments. These will be acquired from $form_state['values'] and the + * keys must match the context IDs. + * + * @return + * A new $contexts array containing the replaced contexts. Not all contexts + * may be replaced if, for example, an argument was unable to be converted + * into a context. + */ +function ctools_context_replace_placeholders($contexts, $arguments) { + foreach ($contexts as $cid => $context) { + if (empty($context->empty)) { + continue; + } + + $new_context = NULL; + switch ($context->placeholder['type']) { + case 'relationship': + $relationship = $context->placeholder['conf']; + if (isset($contexts[$relationship['context']])) { + $new_context = ctools_context_get_context_from_relationship($relationship, $contexts[$relationship['context']]); + } + break; + case 'argument': + if (isset($arguments[$cid]) && $arguments[$cid] !== '') { + $argument = $context->placeholder['conf']; + $new_context = ctools_context_get_context_from_argument($argument, $arguments[$cid]); + } + break; + case 'context': + if (!empty($arguments[$cid])) { + $context_info = $context->placeholder['conf']; + $new_context = ctools_context_get_context_from_context($context_info, 'context', $arguments[$cid]); + } + break; + } + + if ($new_context && empty($new_context->empty)) { + $contexts[$cid] = $new_context; + } + } + + return $contexts; +} + +/** + * Provide a form array for getting data to replace placeholder contexts + * with real data. + */ +function ctools_context_replace_form(&$form, $contexts) { + foreach ($contexts as $cid => $context) { + if (empty($context->empty)) { + continue; + } + + // Get plugin info from the context which should have been set when the + // empty context was created. + $info = NULL; + $plugin = NULL; + $settings = NULL; + switch ($context->placeholder['type']) { + case 'argument': + $info = $context->placeholder['conf']; + $plugin = ctools_get_argument($info['name']); + $settings = $info['settings']; + break; + + case 'context': + $info = $context->placeholder['conf']; + $plugin = ctools_get_context($info['name']); + $settings = $info['context_settings']; + break; + } + + // Ask the plugin where the form is. + if ($plugin && isset($plugin['placeholder form'])) { + if (is_array($plugin['placeholder form'])) { + $form[$cid] = $plugin['placeholder form']; + } + else if (function_exists($plugin['placeholder form'])) { + $widget = $plugin['placeholder form']($info['settings']); + if ($widget) { + $form[$cid] = $widget; + } + } + + if (!empty($form[$cid])) { + $form[$cid]['#title'] = t('@identifier (@keyword)', array('@keyword' => '%' . $context->keyword, '@identifier' => $context->identifier)); + } + } + } +} + +// --------------------------------------------------------------------------- +// Functions related to loading access control plugins + +/** + * Fetch metadata on a specific access control plugin. + * + * @param $name + * Name of a plugin. + * + * @return + * An array with information about the requested access control plugin. + */ +function ctools_get_access_plugin($name) { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'access', $name); +} + +/** + * Fetch metadata for all access control plugins. + * + * @return + * An array of arrays with information about all available access control plugins. + */ +function ctools_get_access_plugins() { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'access'); +} + +/** + * Fetch a list of access plugins that are available for a given list of + * contexts. + * + * if 'logged-in-user' is not in the list of contexts, it will be added as + * this is required. + */ +function ctools_get_relevant_access_plugins($contexts) { + if (!isset($contexts['logged-in-user'])) { + $contexts['logged-in-user'] = ctools_access_get_loggedin_context(); + } + + $all_plugins = ctools_get_access_plugins(); + $plugins = array(); + foreach ($all_plugins as $id => $plugin) { + if (!empty($plugin['required context']) && !ctools_context_match_requirements($contexts, $plugin['required context'])) { + continue; + } + $plugins[$id] = $plugin; + } + + return $plugins; +} + +/** + * Create a context for the logged in user. + */ +function ctools_access_get_loggedin_context() { + global $user; + $context = ctools_context_create('user', $user); + $context->identifier = t('Logged in user'); + $context->keyword = 'viewer'; + $context->id = 0; + + return $context; +} + +/** + * Get a summary of an access plugin's settings. + */ +function ctools_access_summary($plugin, $contexts, $test) { + if (!isset($contexts['logged-in-user'])) { + $contexts['logged-in-user'] = ctools_access_get_loggedin_context(); + } + + $description = ''; + if ($function = ctools_plugin_get_function($plugin, 'summary')) { + $required_context = isset($plugin['required context']) ? $plugin['required context'] : array(); + $context = isset($test['context']) ? $test['context'] : array(); + $description = $function($test['settings'], ctools_context_select($contexts, $required_context, $context), $plugin); + } + + if (!empty($test['not'])) { + $description = "NOT ($description)"; + } + + return $description; +} + +/** + * Get a summary of a group of access plugin's settings. + */ +function ctools_access_group_summary($access, $contexts) { + if (empty($access['plugins'])) { + return; + } + + $descriptions = array(); + foreach ($access['plugins'] as $id => $test) { + $plugin = ctools_get_access_plugin($test['name']); + $descriptions[] = ctools_access_summary($plugin, $contexts, $test); + } + + $separator = $access['logic'] == 'and' ? t(', and ') : t(', or '); + return implode($separator, $descriptions); +} + +/** + * Determine if the current user has access via plugin. + * + * @param $settings + * An array of settings theoretically set by the user. + * @param $contexts + * An array of zero or more contexts that may be used to determine if + * the user has access. + * + * @return + * TRUE if access is granted, false if otherwise. + */ +function ctools_access($settings, $contexts = array()) { + if (empty($settings['plugins'])) { + return TRUE; + } + + if (!isset($settings['logic'])) { + $settings['logic'] = 'and'; + } + + if (!isset($contexts['logged-in-user'])) { + $contexts['logged-in-user'] = ctools_access_get_loggedin_context(); + } + + foreach ($settings['plugins'] as $test) { + $pass = FALSE; + $plugin = ctools_get_access_plugin($test['name']); + if ($plugin && $function = ctools_plugin_get_function($plugin, 'callback')) { + // Do we need just some contexts or all of them? + if (!empty($plugin['all contexts'])) { + $test_contexts = $contexts; + } + else { + $required_context = isset($plugin['required context']) ? $plugin['required context'] : array(); + $context = isset($test['context']) ? $test['context'] : array(); + $test_contexts = ctools_context_select($contexts, $required_context, $context); + } + + $pass = $function($test['settings'], $test_contexts, $plugin); + if (!empty($test['not'])) { + $pass = !$pass; + } + } + + if ($pass && $settings['logic'] == 'or') { + // Pass if 'or' and this rule passed. + return TRUE; + } + else if (!$pass && $settings['logic'] == 'and') { + // Fail if 'and' and htis rule failed. + return FALSE; + } + } + + // Return TRUE if logic was and, meaning all rules passed. + // Return FALSE if logic was or, meaning no rule passed. + return $settings['logic'] == 'and'; +} + +/** + * Create default settings for a new access plugin. + * + * @param $plugin + * The access plugin being used. + * + * @return + * A default configured test that should be placed in $access['plugins']; + */ +function ctools_access_new_test($plugin) { + $test = array( + 'name' => $plugin['name'], + 'settings' => array(), + ); + + // Set up required context defaults. + if (isset($plugin['required context'])) { + if (is_object($plugin['required context'])) { + $test['context'] = ''; + } + else { + $test['context'] = array(); + foreach ($plugin['required context'] as $required) { + $test['context'][] = ''; + } + } + } + + + $default = NULL; + if (isset($plugin['default'])) { + $default = $plugin['default']; + } + elseif (isset($plugin['defaults'])) { + $default = $plugin['defaults']; + } + + // Setup plugin defaults. + if (isset($default)) { + if (is_array($default)) { + $test['settings'] = $default; + } + else if (function_exists($default)) { + $test['settings'] = $default(); + } + else { + $test['settings'] = array(); + } + } + + return $test; +} + +/** + * Apply restrictions to contexts based upon the access control configured. + * + * These restrictions allow the UI to not show content that may not + * be relevant to all types of a particular context. + */ +function ctools_access_add_restrictions($settings, $contexts) { + if (empty($settings['plugins'])) { + return; + } + + if (!isset($settings['logic'])) { + $settings['logic'] = 'and'; + } + + // We're not going to try to figure out restrictions on the or. + if ($settings['logic'] == 'or' && count($settings['plugins']) > 1) { + return; + } + + foreach ($settings['plugins'] as $test) { + $plugin = ctools_get_access_plugin($test['name']); + if ($plugin && $function = ctools_plugin_get_function($plugin, 'restrictions')) { + $required_context = isset($plugin['required context']) ? $plugin['required context'] : array(); + $context = isset($test['context']) ? $test['context'] : array(); + $contexts = ctools_context_select($contexts, $required_context, $context); + $function($test['settings'], $contexts); + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.menu.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..3cba9325024303f67eeac067a7c8b027557c8d38 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.menu.inc @@ -0,0 +1,39 @@ +<?php + +/** + * @file + * Contains menu item registration for the context tool. + * + * The menu items registered are AJAX callbacks for the context configuration + * popups. They are kept separately for organizational purposes. + */ + +function ctools_context_menu(&$items) { + $base = array( + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + 'file' => 'includes/context-admin.inc', + ); + $items['ctools/context/ajax/add'] = array( + 'page callback' => 'ctools_context_ajax_item_add', + ) + $base; + $items['ctools/context/ajax/configure'] = array( + 'page callback' => 'ctools_context_ajax_item_edit', + ) + $base; + $items['ctools/context/ajax/delete'] = array( + 'page callback' => 'ctools_context_ajax_item_delete', + ) + $base; + + // For the access system + $base['file'] = 'includes/context-access-admin.inc'; + $items['ctools/context/ajax/access/add'] = array( + 'page callback' => 'ctools_access_ajax_add', + ) + $base; + $items['ctools/context/ajax/access/configure'] = array( + 'page callback' => 'ctools_access_ajax_edit', + ) + $base; + $items['ctools/context/ajax/access/delete'] = array( + 'page callback' => 'ctools_access_ajax_delete', + ) + $base; + +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.theme.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..f8f93bfae089d84ab471efe6570ea8464d14daba --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/context.theme.inc @@ -0,0 +1,323 @@ +<?php + +/** + * @file + * Contains theme registry and theme implementations for the context tool. + */ + +/** + * Implementation of hook_theme() + */ +function ctools_context_theme(&$theme) { + $theme['ctools_context_list'] = array( + 'arguments' => array('object'), + 'file' => 'includes/context.theme.inc', + ); + $theme['ctools_context_list_no_table'] = array( + 'arguments' => array('object'), + 'file' => 'includes/context.theme.inc', + ); + $theme['ctools_context_item_form'] = array( + 'arguments' => array('form'), + 'file' => 'includes/context.theme.inc', + ); + $theme['ctools_context_item_row'] = array( + 'arguments' => array('type', 'form', 'position', 'count', 'with_tr' => TRUE), + 'file' => 'includes/context.theme.inc', + ); + + // For the access plugin + $theme['ctools_access_admin_add'] = array( + 'arguments' => array('form'), + 'file' => 'includes/context-admin.inc', + ); +} + +/** + * Theme the form item for the context entry. + */ +function theme_ctools_context_item_row($type, $form, $position, $count, $with_tr = TRUE) { + $output = '<td class="title"> ' . drupal_render($form['title']) . '</td>'; + if (!empty($form['position'])) { + $output .= '<td class="position"> ' . drupal_render($form['position']) . '</td>'; + } + $output .= '<td class="operation">' . drupal_render($form['settings']); + $output .= drupal_render($form['remove']) . '</td>'; + + if ($with_tr) { + $output = '<tr id="' . $type . '-row-' . $position . '" class="draggable ' . $type . '-row ' . ($count % 2 ? 'even' : 'odd') . '">' . $output . '</tr>'; + } + return $output; +} + +/** + * Display the context item. + */ +function theme_ctools_context_item_form($form) { + $output = ''; + $type = $form['#ctools_context_type']; + $module = $form['#ctools_context_module']; + $name = $form['#object_name']; + + $type_info = ctools_context_info($type); + + if (!empty($form[$type]) && empty($form['#only_buttons'])) { + $count = 0; + $rows = ''; + foreach (array_keys($form[$type]) as $id) { + if (!is_numeric($id)) { + continue; + } + $rows .= theme('ctools_context_item_row', $type, $form[$type][$id], $id, $count++); + } + + $output .= '<table id="' . $type . '-table">'; + $output .= '<thead>'; + $output .= '<tr>'; + $output .= '<th class="title">' . $type_info['title'] . '</th>'; + if (!empty($type_info['sortable']) && $count) { + $output .= '<th class="position">' . t('Weight') . '</th>'; + } + $output .= '<th class="operation">' . t('Operation') . '</th>'; + $output .= '</tr>'; + $output .= '</thead>'; + $output .= '<tbody>'; + + $output .= $rows; + + $output .= '</tbody>'; + $output .= '</table>'; + } + + if (!empty($form['buttons'])) { + // Display the add context item. + $row = array(); + $row[] = array('data' => drupal_render($form['buttons'][$type]['item']), 'class' => 'title'); + $row[] = array('data' => drupal_render($form['buttons'][$type]['add']), 'class' => 'add', 'width' => "60%"); + $output .= '<div class="buttons">'; + $output .= drupal_render($form['buttons'][$type]); + $output .= theme('table', array(), array($row), array('id' => $type . '-add-table')); + $output .= '</div>'; + } + if (!empty($form['description'])) { + $output .= drupal_render($form['description']); + } + + if (!empty($type_info['sortable'])) { + drupal_add_tabledrag($type . '-table', 'order', 'sibling', 'drag-position'); + } + + return $output; +} + +/** + * Create a visible list of all the contexts available on an object. + * Assumes arguments, relationships and context objects. + * + * Contexts must be preloaded. + */ +function theme_ctools_context_list($object, $header = '', $description = '') { + $titles = array(); + $output = ''; + $count = 1; + + $contexts = ctools_context_load_contexts($object); + + // Describe 'built in' contexts. + if (!empty($object->base_contexts)) { + foreach ($object->base_contexts as $id => $context) { + $output .= '<tr>'; + $output .= '<td valign="top"><em>' . t('Built in context') . '</em></td>'; + $desc = check_plain($context->identifier); + if (isset($context->keyword)) { + $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $context->keyword)); + foreach (ctools_context_get_converters('%' . $context->keyword . ':', $context) as $keyword => $title) { + $desc .= '<br />' . t('@keyword --> @title', array('@keyword' => $keyword, '@title' => $title)); + } + $desc .= '</div>'; + + } + if (isset($context->description)) { + $desc .= '<div class="description">' . filter_xss_admin($context->description) . '</div>'; + } + $output .= '<td>' . $desc . '</td>'; + $output .= '</tr>'; + $titles[$id] = $context->identifier; + } + } + + // First, make a list of arguments. Arguments are pretty simple. + if (!empty($object->arguments)) { + foreach ($object->arguments as $argument) { + $output .= '<tr>'; + $output .= '<td valign="top"><em>' . t('Argument @count', array('@count' => $count)) . '</em></td>'; + $desc = check_plain($argument['identifier']); + if (isset($argument['keyword'])) { + $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $argument['keyword'])); + if (isset($contexts[ctools_context_id($argument, 'argument')])) { + foreach (ctools_context_get_converters('%' . $argument['keyword'] . ':', $contexts[ctools_context_id($argument, 'argument')]) as $keyword => $title) { + $desc .= '<br />' . t('@keyword --> @title', array('@keyword' => $keyword, '@title' => $title)); + } + } + $desc .= '</div>'; + } + $output .= '<td>' . $desc . '</td>'; + $output .= '</tr>'; + $titles[ctools_context_id($argument, 'argument')] = $argument['identifier']; + $count++; + } + } + + $count = 1; + // Then, make a nice list of contexts. + if (!empty($object->contexts)) { + foreach ($object->contexts as $context) { + $output .= '<tr>'; + $output .= '<td valign="top"><em>' . t('Context @count', array('@count' => $count)) . '</em></td>'; + $desc = check_plain($context['identifier']); + if (isset($context['keyword'])) { + $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $context['keyword'])); + foreach (ctools_context_get_converters('%' . $context['keyword'] . ':', $contexts[ctools_context_id($context, 'context')]) as $keyword => $title) { + $desc .= '<br />' . t('@keyword --> @title', array('@keyword' => $keyword, '@title' => $title)); + } + $desc .= '</div>'; + } + $output .= '<td>' . $desc . '</td>'; + $output .= '</tr>'; + $titles[ctools_context_id($context)] = $context['identifier']; + $count++; + } + } + + // And relationships + if (!empty($object->relationships)) { + foreach ($object->relationships as $relationship) { + $output .= '<tr>'; + if (is_array($relationship['context'])) { + $rtitles = array(); + foreach ($relationship['context'] as $cid) { + $rtitles[$cid] = $titles[$cid]; + } + $title = implode(' + ', $rtitles); + } + else { + $title = $titles[$relationship['context']]; + } + $output .= '<td valign="top"><em>' . t('From "@title"', array('@title' => $title)) . '</em></td>'; + $desc = check_plain($relationship['identifier']); + if (isset($relationship['keyword'])) { + $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $relationship['keyword'])); + foreach (ctools_context_get_converters('%' . $relationship['keyword'] . ':', $contexts[ctools_context_id($relationship, 'relationship')]) as $keyword => $title) { + $desc .= '<br />' . t('@keyword --> @title', array('@keyword' => $keyword, '@title' => $title)); + } + $desc .= '</div>'; + } + $output .= '<td>' . $desc . '</td>'; + $output .= '</tr>'; + $titles[ctools_context_id($relationship, 'relationship')] = $relationship['identifier']; + $count++; + } + } + + $head = ''; + if ($header) { + if ($description) { + $header .= '<div class="description">' . $description . '</div>'; + } + $head .= '<thead><tr>'; + $head .= '<th colspan="2">' . $header . '</th>'; + $head .= '</tr></thead>'; + } + + return $output ? "<table>$head<tbody>$output</tbody></table>\n" : "<table>$head</table>\n"; +} + +/** + * ctools_context_list() but not in a table format because tabledrag + * won't let us have tables within tables and still drag. + */ +function theme_ctools_context_list_no_table($object) { + ctools_add_css('context'); + $titles = array(); + $output = ''; + $count = 1; + // Describe 'built in' contexts. + if (!empty($object->base_contexts)) { + foreach ($object->base_contexts as $id => $context) { + $output .= '<div class="ctools-context-holder clear-block">'; + $output .= '<div class="ctools-context-title">' . t('Built in context') . '</div>'; + $desc = check_plain($context->identifier); + if (isset($context->keyword)) { + $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $context->keyword)) . '</div>'; + } + if (isset($context->description)) { + $desc .= '<div class="description">' . filter_xss_admin($context->description) . '</div>'; + } + $output .= '<div class="ctools-context-content">' . $desc . '</div>'; + $output .= '</div>'; + $titles[$id] = $context->identifier; + $count++; + } + } + + // First, make a list of arguments. Arguments are pretty simple. + if (!empty($object->arguments)) { + foreach ($object->arguments as $argument) { + $output .= '<div class="ctools-context-holder clear-block">'; + $output .= '<div class="ctools-context-title">' . t('Argument @count', array('@count' => $count)) . '</div>'; + $desc = check_plain($argument['identifier']); + if (isset($argument['keyword'])) { + $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $argument['keyword'])) . '</div>'; + } + $output .= '<div class="ctools-context-content">' . $desc . '</div>'; + $output .= '</div>'; + $titles[ctools_context_id($argument, 'argument')] = $argument['identifier']; + $count++; + } + } + $count = 1; + // Then, make a nice list of contexts. + if (!empty($object->contexts)) { + foreach ($object->contexts as $context) { + $output .= '<div class="ctools-context-holder clear-block">'; + $output .= '<div class="ctools-context-title">' . t('Context @count', array('@count' => $count)) . '</div>'; + $desc = check_plain($context['identifier']); + if (isset($context['keyword'])) { + $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $context['keyword'])) . '</div>'; + } + $output .= '<div class="ctools-context-content">' . $desc . '</div>'; + $output .= '</div>'; + $titles[ctools_context_id($context)] = $context['identifier']; + $count++; + } + } + // And relationships + if (!empty($object->relationships)) { + foreach ($object->relationships as $relationship) { + $output .= '<div class="ctools-context-holder clear-block">'; + if (is_array($relationship['context'])) { + $rtitles = array(); + foreach ($relationship['context'] as $cid) { + $rtitles[$cid] = $titles[$cid]; + } + $title = implode(' + ', $rtitles); + } + else { + $title = $titles[$relationship['context']]; + } + + $output .= '<div class="ctools-context-title">' . t('From "@title"', array('@title' => $title)) . '</div>'; + $desc = check_plain($relationship['identifier']); + if (isset($relationship['keyword'])) { + $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $relationship['keyword'])) . '</div>'; + } + $output .= '<div class="ctools-context-content">' . $desc . '</div>'; + $output .= '</div>'; + $titles[ctools_context_id($relationship, 'relationship')] = $relationship['identifier']; + $count++; + } + } + + return $output; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/css.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/css.inc new file mode 100644 index 0000000000000000000000000000000000000000..0c49973477fcc40ad83a76aef04e22727bb3640a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/css.inc @@ -0,0 +1,586 @@ +<?php + +/* + * @file + * CSS filtering functions. Contains a disassembler, filter, compressor, and + * decompressor. + * + * The general usage of this tool is: + * + * To simply filter CSS: + * @code + * $filtered_css = ctools_css_filter($css, TRUE); + * @endcode + * + * In the above, if the second argument is TRUE, the returned CSS will + * be compressed. Otherwise it will be returned in a well formatted + * syntax. + * + * To cache unfiltered CSS in a file, which will be filtered: + * + * @code + * $filename = ctools_css_cache($css, TRUE); + * @endcode + * + * In the above, if the second argument is FALSE, the CSS will not be filtered. + * + * This file will be cached within the Drupal files system. This system cannot + * detect when this file changes, so it is YOUR responsibility to remove and + * re-cache this file when the CSS is changed. Your system should also contain + * a backup method of re-generating the CSS cache in case it is removed, so + * that it is easy to force a re-cache by simply deleting the contents of the + * directory. + * + * Finally, if for some reason your application cannot store the filename + * (which is true of Panels where the style can't force the display to + * resave unconditionally) you can use the ctools storage mechanism. You + * simply have to come up with a unique Id: + * + * @code + * $filename = ctools_css_store($id, $css, TRUE); + * @endcode + * + * Then later on: + * @code + * $filename = ctools_css_retrieve($id); + * ctools_css_add_css($filename); + * @endcode + * + * The CSS that was generated will be stored in the database, so even if the + * file was removed the cached CSS will be used. If the CSS cache is + * cleared you may be required to regenerate your CSS. This will normally + * only be cleared by an administrator operation, not during normal usage. + * + * You may remove your stored CSS this way: + * + * @code + * ctools_css_clear($id); + * @endcode + */ + +/** + * Store CSS with a given id and return the filename to use. + * + * This function associates a piece of CSS with an id, and stores the + * cached filename and the actual CSS for later use with + * ctools_css_retrieve. + */ +function ctools_css_store($id, $css, $filter = TRUE) { + $filename = db_result(db_query("SELECT filename FROM {ctools_css_cache} WHERE cid = '%s'", $id)); + if ($filename && file_exists($filename)) { + file_delete($filename); + } + // Remove any previous records. + db_query("DELETE FROM {ctools_css_cache} WHERE cid = '%s'", $id); + + $filename = ctools_css_cache($css, $filter); + + db_query("INSERT INTO {ctools_css_cache} (cid, filename, css, filter) VALUES ('%s', '%s', '%s', %d)", $id, $filename, $css, $filter); + + return $filename; +} + +/** + * Retrieve a filename associated with an id of previously cached CSS. + * + * This will ensure the file still exists and, if not, create it. + */ +function ctools_css_retrieve($id) { + $cache = db_fetch_object(db_query("SELECT * FROM {ctools_css_cache} WHERE cid = '%s'", $id)); + if (!$cache) { + return; + } + + if (!file_exists($cache->filename)) { + $filename = ctools_css_cache($cache->css, $cache->filter); + if ($filename != $cache->filename) { + db_query("UPDATE {ctools_css_cache} SET filename = '%s' WHERE cid = '%s'", $filename, $id); + $cache->filename = $filename; + } + } + + return $cache->filename; +} + +/** + * Remove stored CSS and any associated file. + */ +function ctools_css_clear($id) { + $cache = db_fetch_object(db_query("SELECT * FROM {ctools_css_cache} WHERE cid = '%s'", $id)); + if (!$cache) { + return; + } + + if (file_exists($cache->filename)) { + file_delete($cache->filename); + // If we remove an existing file, there may be cached pages that refer + // to it. We must get rid of them: + cache_clear_all(); + } + + db_query("DELETE FROM {ctools_css_cache} WHERE cid = '%s'", $id); +} + +/** + * Write a chunk of CSS to a temporary cache file and return the file name. + * + * This function optionally filters the CSS (always compressed, if so) and + * generates a unique filename based upon md5. It returns that filename that + * can be used with ctools_css_add_css(). Note that as a cache file, technically + * this file is volatile so it should be checked before it is used to ensure + * that it exists. + * + * You can use file_exists() to test for the file and file_delete() to remove + * it if it needs to be cleared. + * + * @param $css + * A chunk of well-formed CSS text to cache. + * @param $filter + * If TRUE the css will be filtered. If FALSE the text will be cached + * as-is. + * + * @return $filename + * The filename the CSS will be cached in. + */ +function ctools_css_cache($css, $filter = TRUE) { + if ($filter) { + $css = ctools_css_filter($css); + } + + // Create the css/ within the files folder. + $path = file_create_path('ctools/css'); + if (!file_check_directory($path)) { + $path = file_directory_path() . '/ctools'; + file_check_directory($path, FILE_CREATE_DIRECTORY); + $path .= '/css'; + file_check_directory($path, FILE_CREATE_DIRECTORY); + } + + if (!file_check_directory($path)) { + drupal_set_message(t('Unable to create CTools CSS cache directory. Check the permissions on your files directory.'), 'error'); + return; + } + + // @todo Is this slow? Does it matter if it is? + $filename = $path . '/' . md5($css) . '.css'; + + // This will do renames if the file already exists, ensuring we don't + // accidentally overwrite other files who share the same md5. Yes this + // is a very miniscule chance but it's safe. + $filename = file_save_data($css, $filename); + + return $filename; +} + +/** + * Add a CTools CSS file to the page. + * + * Because drupal_add_css() does not handle files that it cannot stat, it + * can't add files that are stored in a private file system. This will + * will check to see if we're using the private file system and use + * drupal_set_html_head() instead if that is the case. + * + * Sadly that will preclude aggregation of any sort, but there doesn't seem to + * be any ways around that. Also it will screw with stylesheet order. Again, + * sorry. + */ +function ctools_css_add_css($filename = NULL, $type = 'module', $media = 'all', $preprocess = TRUE) { + switch (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)) { + case FILE_DOWNLOADS_PUBLIC: + drupal_add_css($filename, $type, $media, $preprocess); + break; + case FILE_DOWNLOADS_PRIVATE: + $path = file_create_path($filename); + if ($path) { + $url = file_create_url($path); + } + else { + $url = $filename; + } + + $output = '<link type="text/css" rel="stylesheet" media="' . $media . '" href="' . $url . '" />'."\n"; + drupal_set_html_head($output); + } + +} + +/** + * Filter a chunk of CSS text. + * + * This function disassembles the CSS into a raw format that makes it easier + * for our tool to work, then runs it through the filter and reassembles it. + * If you find that you want the raw data for some reason or another, you + * can use the disassemble/assemble functions yourself. + * + * @param $css + * The CSS text to filter. + * @param $compressed + * If true, generate compressed output; if false, generate pretty output. + * Defaults to TRUE. + */ +function ctools_css_filter($css, $compressed = TRUE) { + $css_data = ctools_css_disassemble($css); + + // Note: By using this function yourself you can control the allowed + // properties and values list. + $filtered = ctools_css_filter_css_data($css_data); + + return $compressed ? ctools_css_compress($filtered) : ctools_css_assemble($filtered); +} + +/** + * Re-assemble a css string and format it nicely. + * + * @param array $css_data + * An array of css data, as produced by @see ctools_css_disassemble() + * disassembler and the @see ctools_css_filter_css_data() filter. + * + * @return string $css + * css optimized for human viewing. + */ +function ctools_css_assemble($css_data) { + // Initialize the output. + $css = ''; + // Iterate through all the statements. + foreach ($css_data as $selector_str => $declaration) { + // Add the selectors, separating them with commas and line feeds. + $css .= strpos($selector_str, ',') === FALSE ? $selector_str : str_replace(", ", ",\n", $selector_str); + // Add the opening curly brace. + $css .= " {\n"; + // Iterate through all the declarations. + foreach ($declaration as $property => $value) { + $css .= " " . $property . ": " . $value . ";\n"; + } + // Add the closing curly brace. + $css .= "}\n\n"; + } + // Return the output. + return $css; +} + +/** + * Compress css data (filter it first!) to optimize for use on view. + * + * @param array $css_data + * An array of css data, as produced by @see ctools_css_disassemble() + * disassembler and the @see ctools_css_filter_css_data() filter. + * + * @return string $css + * css optimized for use. + */ +function ctools_css_compress($css_data) { + // Initialize the output. + $css = ''; + // Iterate through all the statements. + foreach ($css_data as $selector_str => $declaration) { + if (empty($declaration)) { + // Skip this statement if filtering removed all parts of the declaration. + continue; + } + // Add the selectors, separating them with commas. + $css .= $selector_str; + // And, the opening curly brace. + $css .= "{"; + // Iterate through all the statement properties. + foreach ($declaration as $property => $value) { + $css .= $property . ':' . $value . ';'; + } + // Add the closing curly brace. + $css .= "}"; + } + // Return the output. + return $css; +} + +/** + * Disassemble the css string. + * + * Strip the css of irrelevant characters, invalid/malformed selectors and + * declarations, and otherwise prepare it for processing. + * + * @param string $css + * A string containing the css to be disassembled. + * + * @return array $disassembled_css + * An array of disassembled, slightly cleaned-up/formatted css statements. + */ +function ctools_css_disassemble($css) { + $disassembled_css = array(); + // Remove comments. + $css = preg_replace("/\/\*(.*)?\*\//Usi", "", $css); + // Split out each statement. Match either a right curly brace or a semi-colon + // that precedes a left curly brace with no right curly brace separating them. + $statements = preg_split('/}|;(?=[^}]*{)/', $css); + + // If we have any statements, parse them. + if (!empty($statements)) { + // Iterate through all of the statements. + foreach ($statements as $statement) { + // Get the selector(s) and declaration. + if (empty($statement) || !strpos($statement, '{')) { + continue; + } + + list($selector_str, $declaration) = explode('{', $statement); + + // If the selector exists, then disassemble it, check it, and regenerate + // the selector string. + $selector_str = empty($selector_str) ? FALSE : _ctools_css_disassemble_selector($selector_str); + if (empty($selector_str)) { + // No valid selectors. Bomb out and start the next item. + continue; + } + + // Disassemble the declaration, check it and tuck it into an array. + if (!isset($disassembled_css[$selector_str])) { + $disassembled_css[$selector_str] = array(); + } + $disassembled_css[$selector_str] += _ctools_css_disassemble_declaration($declaration); + } + } + return $disassembled_css; +} + +function _ctools_css_disassemble_selector($selector_str) { + // Get all selectors individually. + $selectors = explode(",", trim($selector_str)); + // Iterate through all the selectors, sanity check them and return if they + // pass. Note that this handles 0, 1, or more valid selectors gracefully. + foreach ($selectors as $key => $selector) { + // Replace un-needed characters and do a little cleanup. + $selector = preg_replace("/[\n|\t|\\|\s]+/", ' ', trim($selector)); + // Make sure this is still a real selector after cleanup. + if (!empty($selector)) { + $selectors[$key] = $selector; + } + else { + // Selector is no good, so we scrap it. + unset($selectors[$key]); + } + } + // Check for malformed selectors; if found, we skip this declaration. + if (empty($selectors)) { + return FALSE; + } + return implode(', ', $selectors); +} + +function _ctools_css_disassemble_declaration($declaration) { + $formatted_statement = array(); + $propval_pairs = explode(";", $declaration); + // Make sure we actually have some properties to work with. + if (!empty($propval_pairs)) { + // Iterate through the remains and parse them. + foreach ($propval_pairs as $key => $propval_pair) { + // Check that we have a ':', otherwise it's an invalid pair. + if (strpos($propval_pair, ':') === FALSE) { + continue; + } + // Clean up the current property-value pair. + $propval_pair = preg_replace("/[\n|\t|\\|\s]+/", ' ', trim($propval_pair)); + // Explode the remaining fragements some more, but clean them up first. + list($property, $value) = explode(':', $propval_pair, 2); + // If the property survived, toss it onto the stack. + if (!empty($property)) { + $formatted_statement[trim($property)] = trim($value); + } + } + } + return $formatted_statement; +} + +/** + * Run disassembled $css through the filter. + * + * @param $css + * CSS code disassembled by ctools_dss_disassemble(). + * @param $allowed_properties + * A list of properties that are allowed by the filter. If empty + * ctools_css_filter_default_allowed_properties() will provide the + * list. + * @param $allowed_values + * A list of values that are allowed by the filter. If empty + * ctools_css_filter_default_allowed_values() will provide the + * list. + * + * @return + * An array of disassembled, filtered CSS. + */ +function ctools_css_filter_css_data($css, $allowed_properties = array(), $allowed_values = array(), $allowed_values_regex = '', $disallowed_values_regex = '') { +//function ctools_css_filter_css_data($css, &$filtered = NULL, $allowed_properties = array(), $allowed_values = array(), $allowed_values_regex = '', $disallowed_values_regex = '') { + // Retrieve the default list of allowed properties if none is provided. + $allowed_properties = !empty($allowed_properties) ? $allowed_properties : ctools_css_filter_default_allowed_properties(); + // Retrieve the default list of allowed values if none is provided. + $allowed_values = !empty($allowed_values) ? $allowed_values : ctools_css_filter_default_allowed_values(); + // Define allowed values regex if none is provided. + $allowed_values_regex = !empty($allowed_values_regex) ? $allowed_values_regex : '/(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)/'; + // Define disallowed url() value contents, if none is provided. + // $disallowed_values_regex = !empty($disallowed_values_regex) ? $disallowed_values_regex : '/[url|expression]\s*\(\s*[^\s)]+?\s*\)\s*/'; + $disallowed_values_regex = !empty($disallowed_values_regex) ? $disallowed_values_regex : '/(url|expression)/'; + + foreach ($css as $selector_str => $declaration) { + foreach ($declaration as $property => $value) { + if (!in_array($property, $allowed_properties)) { + // $filtered['properties'][$selector_str][$property] = $value; + unset($css[$selector_str][$property]); + continue; + } + $value = str_replace('!important', '', $value); + if (preg_match($disallowed_values_regex, $value) || !(in_array($value, $allowed_values) || preg_match($allowed_values_regex, $value))) { + // $filtered['values'][$selector_str][$property] = $value; + unset($css[$selector_str][$property]); + continue; + } + } + } + return $css; +} + +/** + * Provide a deafult list of allowed properties by the filter. + */ +function ctools_css_filter_default_allowed_properties() { + return array( + 'azimuth', + 'background', + 'background-color', + 'background-image', + 'background-repeat', + 'background-attachment', + 'background-position', + 'border', + 'border-top-width', + 'border-right-width', + 'border-bottom-width', + 'border-left-width', + 'border-width', + 'border-top-color', + 'border-right-color', + 'border-bottom-color', + 'border-left-color', + 'border-color', + 'border-top-style', + 'border-right-style', + 'border-bottom-style', + 'border-left-style', + 'border-style', + 'border-top', + 'border-right', + 'border-bottom', + 'border-left', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'margin', + 'margin-top', + 'margin-right', + 'margin-bottom', + 'margin-left', + 'overflow', + 'padding', + 'padding-top', + 'padding-right', + 'padding-bottom', + 'padding-left', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'text-transform', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', + 'fill', + 'fill-opacity', + 'fill-rule', + 'stroke', + 'stroke-width', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-opacity', + ); +} + +/** + * Provide a default list of allowed values by the filter. + */ +function ctools_css_filter_default_allowed_values() { + return array( + 'auto', + 'aqua', + 'black', + 'block', + 'blue', + 'bold', + 'both', + 'bottom', + 'brown', + 'capitalize', + 'center', + 'collapse', + 'dashed', + 'dotted', + 'fuchsia', + 'gray', + 'green', + 'italic', + 'inherit', + 'left', + 'lime', + 'lowercase', + 'maroon', + 'medium', + 'navy', + 'normal', + 'nowrap', + 'olive', + 'pointer', + 'purple', + 'red', + 'right', + 'solid', + 'silver', + 'teal', + 'top', + 'transparent', + 'underline', + 'uppercase', + 'white', + 'yellow', + ); +} + +/** + * Delegated implementation of hook_flush_caches() + */ +function ctools_css_flush_caches() { + file_scan_directory(file_create_path('ctools/css'), '.*', array('.', '..', 'CVS'), 'file_delete', TRUE); + db_query("DELETE FROM {ctools_css_cache}"); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/dependent.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/dependent.inc new file mode 100644 index 0000000000000000000000000000000000000000..fc1696f2d19013671781c08ef688125f83d30364 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/dependent.inc @@ -0,0 +1,153 @@ +<?php + +/** + * @file + * Provide dependent checkboxes that can be easily used in forms. + * + * This system will ensure that form items are invisible if the dependency is + * not met. What this means is that you set the #dependency of an item to a + * list of form ids that must be set, and the list of values that qualify. + * + * For a simple use, setting an item to be dependent upon a select box, if + * any of the listed values are selected, the item will be visible. Otherwise, + * the item will be invisible. + * + * If dependent upon multiple items, use #dependency_count = X to set the + * number of items that must be set in order to make this item visible. This + * defaults to 1. If set to 2, then at least 2 form items in the list must + * have their items set for the item to become visible. + * + * When hiding checkboxes and radios you need to add their id in a div + * manually via #prefix and #suffix since they don't have their own id. You + * actually need to add TWO divs because it's the parent that gets hidden. + * Also be sure to retain the 'expand_checkboxes' in the #process array, + * because the views process will override it. + * + * Fieldsets can not be hidden by default. Adding '#input' => TRUE to the + * fieldset works around that. + * + * For radios, because they are selected a little bit differently, instead of + * using the CSS id, use: radio:NAME where NAME is the #name of the property. + * This can be quickly found by looking at the HTML of the generated form, but + * it is usually derived from the array which contains the item. For example, + * $form['menu']['type'] would have a name of menu[type]. This name is the same + * field that is used to determine where in $form_state['values'] you will find + * the value of the form. + * + * The item that is dependent on, should be set to #tree = TRUE. + * + * Usage: + * + * First, ensure this tool is loaded: + * @code { ctools_include('dependent'); } + * + * On any form item, add + * - @code '#process' => array('ctools_dependent_process'), @endcode + * - @code '#dependency' => array('id-of-form-without-the-#' => array(list, of, values, that, make, this, gadget, visible)), @endcode + * + * A fuller example, that hides the menu title when no menu is selected: + * @code + *function ctools_dependent_example() { + * $form = array(); + * $form['menu'] = array( + * '#type' => 'fieldset', + * '#title' => t('Menu settings'), + * '#tree' => TRUE, + * ); + * $form['menu']['type'] = array( + * '#title' => t('Menu type'), + * '#type' => 'radios', + * '#options' => array( + * 'none' => t('No menu entry'), + * 'normal' => t('Normal menu entry'), + * 'tab' => t('Menu tab'), + * 'default tab' => t('Default menu tab'), + * ), + * '#default_value' => 'none', + * ); + * + * $form['menu']['title'] = array( + * '#title' => t('Title'), + * '#type' => 'textfield', + * '#default_value' => '', + * '#description' => t('If set to normal or tab, enter the text to use for the menu item.'), + * '#process' => array('ctools_dependent_process'), + * '#dependency' => array('radio:menu[type]' => array('normal', 'tab', 'default tab')), + * ); + * + * return system_settings_form($form); + *} + * @endcode + * + * An example for hiding checkboxes using #prefix and #suffix: + * @code + *function ctools_dependent_example_checkbox() { + * $form = array(); + * $form['object'] = array( + * '#type' => 'fieldset', + * '#title' => t('Select object type'), + * '#tree' => TRUE, + * ); + * $form['object']['type'] = array( + * '#title' => t('Object type'), + * '#type' => 'radios', + * '#options' => array( + * 'view' => t('View'), + * 'node' => t('Node'), + * 'field' => t('Field'), + * 'term' => t('Term'), + * ), + * '#default_value' => 'view', + * ); + * + * $form['object']['elements'] = array( + * '#title' => t('Select the elements to load from the node.'), + * '#type' => 'checkboxes', + * '#prefix' => '<div id="edit-elements-wrapper"><div id="edit-elements">', + * '#suffix' => '</div></div>', + * '#process' => array('ctools_dependent_process', 'expand_checkboxes'), + * '#dependency' => array('radio:menu[type]' => array('node')), + * '#options' => array( + * 'body' => t('Body'), + * 'fields' => t('Fields'), + * 'taxonomy' => t('Taxonomy'), + * ), + * '#default_value' => array('body', 'fields'), + * ); + * + * return system_settings_form($form); + *} + * @endcode + */ + +/** + * Process callback to add dependency to form items. + */ +function ctools_dependent_process($element, $edit, &$form_state, &$form) { + if (isset($element['#dependency'])) { + if (!isset($element['#dependency_count'])) { + $element['#dependency_count'] = 1; + } + if (!isset($element['#dependency_type'])) { + $element['#dependency_type'] = 'hide'; + } + + $js = array( + 'values' => $element['#dependency'], + 'num' => $element['#dependency_count'], + 'type' => $element['#dependency_type'], + ); + + if (!empty($form_state['ajax'])) { + $form_state['js settings']['CTools']['dependent'][$element['#id']] = $js; + } + else { + ctools_add_js('dependent'); + $options['CTools']['dependent'][$element['#id']] = $js; + drupal_add_js($options, 'setting'); + } + } + + return $element; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/dropdown.theme.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/dropdown.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..2a2819acaae4c18dbeae7d8d724325e032afb48c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/dropdown.theme.inc @@ -0,0 +1,87 @@ +<?php + +/** + * @file + * Provide a javascript based dropdown menu. + * + * The dropdown menu will show up as a clickable link; when clicked, + * a small menu will slide down beneath it, showing the list of links. + * + * The dropdown will stay open until either the user has moved the mouse + * away from the box for > .5 seconds, or can be immediately closed by + * clicking the link again. The code is smart enough that if the mouse + * moves away and then back within the .5 second window, it will not + * re-close. + * + * Multiple dropdowns can be placed per page. + * + * If the user does not have javascript enabled, the link will not appear, + * and instead by default the list of links will appear as a normal inline + * list. + * + * The menu is heavily styled by default, and to make it look different + * will require a little bit of CSS. You can apply your own class to the + * dropdown to help ensure that your CSS can override the dropdown's CSS. + * + * In particular, the text, link, background and border colors may need to + * be changed. Please see dropdown.css for information about the existing + * styling. + */ + +/** + * Delegated implementation of hook_theme() + */ +function ctools_dropdown_theme(&$items) { + $items['ctools_dropdown'] = array( + 'arguments' => array('title' => NULL, 'links' => NULL, 'image' => FALSE, 'class' => ''), + 'file' => 'includes/dropdown.theme.inc', + ); +} + +/** + * Create a dropdown menu. + * + * @param $title + * The text to place in the clickable area to activate the dropdown. + * @param $links + * A list of links to provide within the dropdown, suitable for use + * in via Drupal's theme('links'). + * @param $image + * If true, the dropdown link is an image and will not get extra decorations + * that a text dropdown link will. + * @param $class + * An optional class to add to the dropdown's container div to allow you + * to style a single dropdown however you like without interfering with + * other dropdowns. + */ +function theme_ctools_dropdown($title, $links, $image = FALSE, $class = '') { + // Provide a unique identifier for every dropdown on the page. + static $id = 0; + $id++; + + $class = 'ctools-dropdown-no-js ctools-dropdown' . ($class ? (' ' . $class) : ''); + + ctools_add_js('dropdown'); + ctools_add_css('dropdown'); + + $output = ''; + + $output .= '<div class="' . $class . '" id="ctools-dropdown-' . $id . '">'; + $output .= '<div class="ctools-dropdown-link-wrapper">'; + if ($image) { + $output .= '<a href="#" class="ctools-dropdown-link ctools-dropdown-image-link">' . $title . '</a>'; + } + else { + $output .= '<a href="#" class="ctools-dropdown-link ctools-dropdown-text-link">' . check_plain($title) . '</a>'; + } + + $output .= '</div>'; // wrapper + $output .= '<div class="ctools-dropdown-container-wrapper">'; + $output .= '<div class="ctools-dropdown-container">'; + $output .= theme_links($links); + $output .= '</div>'; // container + $output .= '</div>'; // container wrapper + $output .= '</div>'; // dropdown + return $output; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/export-ui.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/export-ui.inc new file mode 100644 index 0000000000000000000000000000000000000000..c6a83de2281901fefb89bc6a2707d012507f3973 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/export-ui.inc @@ -0,0 +1,510 @@ +<?php + +/** + * @file + * Provide a tool for creating UIs for exportable objects. + * + * See Advanced Help for documentation. + */ +/** + * Implementation of hook_ctools_plugin_*. + */ +function ctools_ctools_plugin_export_ui() { + return array( + 'process' => 'ctools_export_ui_process', + ); +} + +/** + * Process an export-ui plugin to provide it with defaults. + */ +function ctools_export_ui_process(&$plugin, $info) { + ctools_include('export'); + + $plugin += array( + 'has menu' => TRUE, + 'title' => $plugin['name'], + 'export' => array(), + 'allowed operations' => array(), + 'menu' => array(), + 'form' => array(), + 'strings' => array(), + 'list' => NULL, + 'access' => 'administer site configuration', + 'use advanced help' => FALSE, + 'advanced help' => array(), + ); + + // Provide CRUD access defaults based on the base 'access' setting: + $plugin += array( + 'create access' => $plugin['access'], + 'delete access' => $plugin['access'], + ); + + if (empty($plugin['has menu'])) { + return; + } + + // The following keys are required and the plugin cannot be processed + // without them. + $keys = array( + 'title singular', + 'title plural', + 'title singular proper', + 'title plural proper', + 'schema', + ); + + foreach ($keys as $key) { + if (empty($plugin[$key])) { + drupal_set_message(t('The plugin definition of @plugin is missing the %key key.', array('%key' => $key, '@plugin' => $plugin['name'])), 'error'); + } + } + + // If we're on the modules page and building a menu, there is a design flaw + // in Drupal core that causes modules to be installed but the schema does + // not become available until AFTER menu rebuild. This helps smooth that + // out. This is a HACK but it should work: + $schema = ctools_export_get_schema($plugin['schema']); + + if (!$schema && $_GET['q'] == 'admin/build/modules/list/confirm') { + $schema = ctools_export_get_schema($plugin['schema'], TRUE); + } + + if (empty($schema)) { + // If we're updating the schema may not have been read yet, so don't report this error in that case. + if (!defined('MAINTENANCE_MODE')) { + drupal_set_message(t('The plugin definition of @plugin cannot locate schema %schema.', array('%schema' => $plugin['schema'], '@plugin' => $plugin['name'])), 'error'); + } + return; + } + + if (empty($schema['export'])) { + drupal_set_message(t('The plugin definition of @plugin uses %schema, but it has no export section.', array('%schema' => $plugin['schema'], '@plugin' => $plugin['name'])), 'error'); + return; + } + + $plugin['export'] += array( + // Add the identifier key from the schema so we don't have to call + // ctools_export_get_schema() just for that. + 'key' => $schema['export']['key'], + ); + + // Add some default fields that appear often in exports + // If these use different keys they can easily be specified in the + // $plugin. + + if (empty($plugin['export']['admin_title']) && !empty($schema['fields']['admin_title'])) { + $plugin['export']['admin_title'] = 'admin_title'; + } + if (empty($plugin['export']['admin_description']) && !empty($schema['fields']['admin_description'])) { + $plugin['export']['admin_description'] = 'admin_description'; + } + + // Define allowed operations, and the name of the operations. + $plugin['allowed operations'] += array( + 'edit' => array('title' => t('Edit')), + 'enable' => array('title' => t('Enable'), 'ajax' => TRUE, 'token' => TRUE), + 'disable' => array('title' => t('Disable'), 'ajax' => TRUE, 'token' => TRUE), + 'revert' => array('title' => t('Revert')), + 'delete' => array('title' => t('Delete')), + 'clone' => array('title' => t('Clone')), + 'import' => array('title' => t('Import')), + 'export' => array('title' => t('Export')), + ); + + $plugin['menu'] += array( + 'menu item' => str_replace(' ', '-', $plugin['name']), + 'menu prefix' => 'admin/build', + 'menu title' => $plugin['title'], + 'menu description' => '', + ); + $base_path = ctools_export_ui_plugin_base_path($plugin); + $prefix_count = count(explode('/', $plugin['menu']['menu prefix'])); + + $plugin['menu'] += array( + // Default menu items that should be declared. + 'items' => array(), + ); + + $plugin['menu']['items'] += array( + 'list callback' => array( + 'path' => '', + // Menu items are translated by the menu system. + // TODO: We need more flexibility in title. The title of the admin page + // is not necessarily the title of the object, plus we need + // plural, singular, proper, not proper, etc. + 'title' => $plugin['menu']['menu title'], + 'description' => $plugin['menu']['menu description'], + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'list'), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'list'), + 'type' => MENU_NORMAL_ITEM, + ), + 'list' => array( + 'path' => 'list', + 'title' => 'List', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'list'), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'list'), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ), + 'add' => array( + 'path' => 'add', + 'title' => 'Add', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'add'), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'add'), + 'type' => MENU_LOCAL_TASK, + ), + 'edit callback' => array( + 'path' => 'list/%ctools_export_ui', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'edit', $prefix_count + 2), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'edit', $prefix_count + 2), + 'type' => MENU_CALLBACK, + ), + 'edit' => array( + 'path' => 'list/%ctools_export_ui/edit', + 'title' => 'Edit', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'edit', $prefix_count + 2), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'edit', $prefix_count + 2), + 'type' => MENU_DEFAULT_LOCAL_TASK, + ), + ); + + if ($plugin['allowed operations']['import']) { + $plugin['menu']['items'] += array( + 'import' => array( + 'path' => 'import', + 'title' => 'Import', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'import'), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'import'), + 'type' => MENU_LOCAL_TASK, + ), + ); + } + + if ($plugin['allowed operations']['export']) { + $plugin['menu']['items'] += array( + 'export' => array( + 'path' => 'list/%ctools_export_ui/export', + 'title' => 'Export', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'export', $prefix_count + 2), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'export', $prefix_count + 2), + 'type' => MENU_LOCAL_TASK, + ), + ); + } + + if ($plugin['allowed operations']['revert']) { + $plugin['menu']['items'] += array( + 'revert' => array( + 'path' => 'list/%ctools_export_ui/revert', + 'title' => 'Revert', + 'page callback' => 'ctools_export_ui_switcher_page', + // Note: Yes, 'delete' op is correct. + 'page arguments' => array($plugin['name'], 'delete', $prefix_count + 2), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'revert', $prefix_count + 2), + 'type' => MENU_CALLBACK, + ), + ); + } + + if ($plugin['allowed operations']['delete']) { + $plugin['menu']['items'] += array( + 'delete' => array( + 'path' => 'list/%ctools_export_ui/delete', + 'title' => 'Delete', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'delete', $prefix_count + 2), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'delete', $prefix_count + 2), + 'type' => MENU_CALLBACK, + ), + ); + } + + if ($plugin['allowed operations']['clone']) { + $plugin['menu']['items'] += array( + 'clone' => array( + 'path' => 'list/%ctools_export_ui/clone', + 'title' => 'Clone', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'clone', $prefix_count + 2), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'clone', $prefix_count + 2), + 'type' => MENU_CALLBACK, + ), + ); + } + + if ($plugin['allowed operations']['enable']) { + $plugin['menu']['items'] += array( + 'enable' => array( + 'path' => 'list/%ctools_export_ui/enable', + 'title' => 'Enable', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'enable', $prefix_count + 2), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'enable', $prefix_count + 2), + 'type' => MENU_CALLBACK, + ), + ); + } + + if ($plugin['allowed operations']['disable']) { + $plugin['menu']['items'] += array( + 'disable' => array( + 'path' => 'list/%ctools_export_ui/disable', + 'title' => 'Disable', + 'page callback' => 'ctools_export_ui_switcher_page', + 'page arguments' => array($plugin['name'], 'disable', $prefix_count + 2), + 'load arguments' => array($plugin['name']), + 'access callback' => 'ctools_export_ui_task_access', + 'access arguments' => array($plugin['name'], 'disable', $prefix_count + 2), + 'type' => MENU_CALLBACK, + ), + ); + } + + // Define some redirects that should happen after edit/add/clone operations. + $plugin['redirect'] = array( + 'add' => $base_path, + 'clone' => $base_path, + 'edit' => $base_path, + 'import' => $base_path, + ); + + // Define form elements. + $plugin['form'] += array( + 'settings' => function_exists($plugin['name'] . '_form') ? $plugin['name'] . '_form' : '', + 'validate' => function_exists($plugin['name'] . '_form_validate') ? $plugin['name'] . '_form_validate' : '', + 'submit' => function_exists($plugin['name'] . '_form_submit') ? $plugin['name'] . '_form_submit' : '', + ); + + // Define strings. + + // For all strings, %title may be filled in at a later time via str_replace + // since we do not know the title now. + $plugin['strings'] += array( + 'title' => array(), + 'confirmation' => array(), + 'help' => array(), + 'message' => array(), + 'advanced help' => array(), + ); + + // Strings used in drupal_set_title(). + $plugin['strings']['title'] += array( + 'add' => t('Add a new @plugin', array('@plugin' => $plugin['title singular'])), + // The "%title" will be replaced in ctools_export_ui_form(), as in this + // stage we dont have the specific exportable object. + 'edit' => t('Edit @plugin %title', array('@plugin' => $plugin['title singular'])), + 'clone' => t('Clone @plugin %title', array('@plugin' => $plugin['title singular'])), + + 'import' => t('Import @plugin', array('@plugin' => $plugin['title singular'])), + 'export' => t('Export @plugin %title', array('@plugin' => $plugin['title singular'])), + ); + + // Strings used in confirmation pages. + $plugin['strings']['confirmation'] += array( + 'revert' => array(), + 'delete' => array(), + 'add' => array(), + 'edit' => array(), + ); + + $plugin['strings']['confirmation']['revert'] += array( + 'question' => t('Are you sure you want to revert %title?'), + 'information' => t('This action will permanently remove any customizations made to this item.'), + 'success' => t('The item has been reverted.'), + ); + + $plugin['strings']['confirmation']['delete'] += array( + 'question' => t('Are you sure you want to delete %title?'), + 'information' => t('This action will permanently remove this item from your database..'), + 'success' => t('The item has been deleted.'), + ); + + $plugin['strings']['confirmation']['add'] += array( + 'success' => t('%title has been created.'), + 'fail' => t('%title could not be created.'), + ); + + $plugin['strings']['confirmation']['edit'] += array( + 'success' => t('%title has been updated.'), + 'fail' => t('%title could not be updated.'), + ); + + // Strings used in $forms. + $plugin['strings']['help'] += array( + 'import' => t('You can import an exported definition by pasting the exported object code into the field below.'), + ); + + // Strings used in drupal_set_message(). + $plugin['strings']['message'] += array( + 'enable' => t('@plugin %title was enabled.', array('@plugin' => $plugin['title singular proper'])), + 'disable' => t('@plugin %title was disabled.', array('@plugin' => $plugin['title singular proper'])), + ); + + // Strings used if advanced help module is enabled. + + + if (!empty($plugin['use advanced help'])) { + if (module_exists('advanced_help')) { + $plugin['advanced help'] += array( + 'enabled' => TRUE, + 'topic' => $plugin['module'], + 'module' => $plugin['module'], + ); + } + else { + $plugin['advanced help'] += array( + 'enabled' => FALSE, + ); + } + + // Get the module name. + $info = drupal_parse_info_file(drupal_get_path('module', $plugin['module']) .'/'. $plugin['module'] .'.info'); + $plugin['strings']['advanced help'] += array( + // The strings to show when the advanced help module is enabled or disabled. + 'enabled' => t('Learn more about the @module module.', array('@module' => $info['name'])), + 'disabled' => t('Learn more about the @module module by enabling the <a href="@path">Advanced help</a> module.', array('@module' => $info['name'], '@path' => 'http://drupal.org/project/advanced_help')), + ); + } + + + +} + +/** + * Get the class to handle creating a list of exportable items. + * + * If a plugin does not define a lister class at all, then the default + * lister class will be used. + * + * @return + * Either the lister class or FALSE if one could not be had. + */ +function ctools_export_ui_get_handler($plugin) { + $cache = &ctools_static(__FUNCTION__, array()); + if (empty($cache[$plugin['name']])) { + // If a list class is not specified by the plugin, fall back to the + // default ctools_export_ui plugin instead. + if (empty($plugin['handler'])) { + $default = ctools_get_export_ui('ctools_export_ui'); + $class = ctools_plugin_get_class($default, 'handler'); + } + else { + $class = ctools_plugin_get_class($plugin, 'handler'); + } + + if ($class) { + $cache[$plugin['name']] = new $class(); + $cache[$plugin['name']]->init($plugin); + } + } + return !empty($cache[$plugin['name']]) ? $cache[$plugin['name']] : FALSE; +} + +/** + * Get the base path from a plugin. + * + * @param $plugin + * The plugin. + * + * @return + * The menu path to the plugin's list. + */ +function ctools_export_ui_plugin_base_path($plugin) { + return $plugin['menu']['menu prefix'] . '/' . $plugin['menu']['menu item']; +} + +/** + * Get the path to a specific menu item from a plugin. + * + * @param $plugin + * The plugin name. + * @param $item_id + * The id in the menu items from the plugin. + * @param $export_key + * The export key of the item being edited, if it exists. + * @return + * The menu path to the plugin's list. + */ +function ctools_export_ui_plugin_menu_path($plugin, $item_id, $export_key = NULL) { + $path = $plugin['menu']['items'][$item_id]['path']; + if ($export_key) { + $path = str_replace('%ctools_export_ui', $export_key, $path); + } + return ctools_export_ui_plugin_base_path($plugin) . '/' . $path; +} + +/** + * Helper function to include CTools plugins and get an export-ui exportable. + * + * @param $plugin_name + * The plugin that should be laoded. + */ +function ctools_get_export_ui($plugin_name) { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'export_ui', $plugin_name); + +} + +/** + * Helper function to include CTools plugins and get all export-ui exportables. + */ +function ctools_get_export_uis() { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'export_ui'); +} + +/** + * Main page callback to manipulate exportables. + * + * This simply loads the object defined in the plugin and hands it off to + * a method based upon the name of the operation in use. This can easily + * be used to add more ops. + */ +function ctools_export_ui_switcher_page($plugin_name, $op) { + $args = func_get_args(); + $js = !empty($_REQUEST['ctools_ajax']); + + // Load the $plugin information + $plugin = ctools_get_export_ui($plugin_name); + $handler = ctools_export_ui_get_handler($plugin); + + if ($handler) { + $method = $op . '_page'; + if (method_exists($handler, $method)) { + // replace the first two arguments: + $args[0] = $js; + $args[1] = $_POST; + return call_user_func_array(array($handler, $method), $args); + } + } + else { + return t('Configuration error. No handler found.'); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/export-ui.menu.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/export-ui.menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..b9d22963ac6b6a01dd53526d34a1772dddc2ebfe --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/export-ui.menu.inc @@ -0,0 +1,17 @@ +<?php + +/** + * Delegated implementation of hook_menu(). + */ +function ctools_export_ui_menu(&$items) { + ctools_include('export-ui'); + + foreach (ctools_get_export_uis() as $plugin) { + if ($plugin['has menu']) { + $handler = ctools_export_ui_get_handler($plugin); + if ($handler) { + $handler->hook_menu($items); + } + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/export.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/export.inc new file mode 100644 index 0000000000000000000000000000000000000000..fa77e674cfafb5d47d99dee0017beb119d7cb1b3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/export.inc @@ -0,0 +1,1030 @@ +<?php + +/** + * @file + * Contains code to make it easier to have exportable objects. + * + * Documentation for exportable objects is contained in help/export.html + */ + +/** + * A bit flag used to let us know if an object is in the database. + */ +define('EXPORT_IN_DATABASE', 0x01); + +/** + * A bit flag used to let us know if an object is a 'default' in code. + */ +define('EXPORT_IN_CODE', 0x02); + +/** + * @defgroup export_crud CRUD functions for export. + * @{ + * export.inc supports a small number of CRUD functions that should always + * work for every exportable object, no matter how complicated. These + * functions allow complex objects to provide their own callbacks, but + * in most cases, the default callbacks will be used. + * + * Note that defaults are NOT set in the $schema because it is presumed + * that a module's personalized CRUD functions will already know which + * $table to use and not want to clutter up the arguments with it. + */ + +/** + * Create a new object for the given $table. + * + * @param $table + * The name of the table to use to retrieve $schema values. This table + * must have an 'export' section containing data or this function + * will fail. + * @param $set_defaults + * If TRUE, which is the default, then default values will be retrieved + * from schema fields and set on the object. + * + * @return + * The loaded object. + */ +function ctools_export_crud_new($table, $set_defaults = TRUE) { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + + if (!empty($export['create callback']) && function_exists($export['create callback'])) { + return $export['create callback']($set_defaults); + } + else { + return ctools_export_new_object($table, $set_defaults); + } +} + +/** + * Load a single exportable object. + * + * @param $table + * The name of the table to use to retrieve $schema values. This table + * must have an 'export' section containing data or this function + * will fail. + * @param $name + * The unique ID to load. The field for this ID will be specified by + * the export key, which normally defaults to 'name'. + * + * @return + * The loaded object. + */ +function ctools_export_crud_load($table, $name) { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + + if (!empty($export['load callback']) && function_exists($export['load callback'])) { + return $export['load callback']($name); + } + else { + $result = ctools_export_load_object($table, 'names', array($name)); + if (isset($result[$name])) { + return $result[$name]; + } + } +} + +/** + * Load all exportable objects of a given type. + * + * @param $table + * The name of the table to use to retrieve $schema values. This table + * must have an 'export' section containing data or this function + * will fail. + * @param $reset + * If TRUE, the static cache of all objects will be flushed prior to + * loading all. This can be important on listing pages where items + * might have changed on the page load. + * @return + * An array of all loaded objects, keyed by the unique IDs of the export key. + */ +function ctools_export_crud_load_all($table, $reset = FALSE) { + $schema = ctools_export_get_schema($table); + if (empty($schema['export'])) { + return array(); + } + + $export = $schema['export']; + + if ($reset) { + ctools_export_load_object_reset($table); + } + + if (!empty($export['load all callback']) && function_exists($export['load all callback'])) { + return $export['load all callback']($reset); + } + else { + return ctools_export_load_object($table, 'all'); + } +} + +/** + * Save a single exportable object. + * + * @param $table + * The name of the table to use to retrieve $schema values. This table + * must have an 'export' section containing data or this function + * will fail. + * @param $object + * The fully populated object to save. + * + * @return + * Failure to write a record will return FALSE. Otherwise SAVED_NEW or + * SAVED_UPDATED is returned depending on the operation performed. The + * $object parameter contains values for any serial fields defined by the $table + */ +function ctools_export_crud_save($table, &$object) { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + + if (!empty($export['save callback']) && function_exists($export['save callback'])) { + return $export['save callback']($object); + } + else { + // Objects should have a serial primary key. If not, simply fail to write. + if (empty($export['primary key'])) { + return FALSE; + } + + $key = $export['primary key']; + if ($object->export_type & EXPORT_IN_DATABASE) { + // Existing record. + $update = array($key); + } + else { + // New record. + $update = array(); + $object->export_type = EXPORT_IN_DATABASE; + } + return drupal_write_record($table, $object, $update); + } +} + +/** + * Delete a single exportable object. + * + * This only deletes from the database, which means that if an item is in + * code, then this is actually a revert. + * + * @param $table + * The name of the table to use to retrieve $schema values. This table + * must have an 'export' section containing data or this function + * will fail. + * @param $object + * The fully populated object to delete, or the export key. + */ +function ctools_export_crud_delete($table, $object) { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + + if (!empty($export['delete callback']) && function_exists($export['delete callback'])) { + return $export['delete callback']($object); + } + else { + // If we were sent an object, get the export key from it. Otherwise + // assume we were sent the export key. + $value = is_object($object) ? $object->{$export['key']} : $object; + db_query("DELETE FROM {" . $table . "} WHERE " . $export['key'] . " = '%s'", $value); + } +} + +/** + * Get the exported code of a single exportable object. + * + * @param $table + * The name of the table to use to retrieve $schema values. This table + * must have an 'export' section containing data or this function + * will fail. + * @param $object + * The fully populated object to delete, or the export key. + * @param $indent + * Any indentation to apply to the code, in case this object is embedded + * into another, for example. + * + * @return + * A string containing the executable export of the object. + */ +function ctools_export_crud_export($table, $object, $indent = '') { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + + if (!empty($export['export callback']) && function_exists($export['export callback'])) { + return $export['export callback']($object, $indent); + } + else { + return ctools_export_object($table, $object, $indent); + } +} + +/** + * Turn exported code into an object. + * + * Note: If the code is poorly formed, this could crash and there is no + * way to prevent this. + * + * @param $table + * The name of the table to use to retrieve $schema values. This table + * must have an 'export' section containing data or this function + * will fail. + * @param $code + * The code to eval to create the object. + * + * @return + * An object created from the export. This object will NOT have been saved + * to the database. In the case of failure, a string containing all errors + * that the system was able to determine. + */ +function ctools_export_crud_import($table, $code) { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + + if (!empty($export['import callback']) && function_exists($export['import callback'])) { + return $export['import callback']($code); + } + else { + ob_start(); + eval($code); + ob_end_clean(); + + if (empty(${$export['identifier']})) { + $errors = ob_get_contents(); + if (empty($errors)) { + $errors = t('No item found.'); + } + return $errors; + } + + $item = ${$export['identifier']}; + + // Set these defaults just the same way that ctools_export_new_object sets + // them. + $item->export_type = NULL; + $item->{$export['export type string']} = t('Local'); + + return $item; + } +} + +/** + * @} + */ + +/** + * Load some number of exportable objects. + * + * This function will cache the objects, load subsidiary objects if necessary, + * check default objects in code and properly set them up. It will cache + * the results so that multiple calls to load the same objects + * will not cause problems. + * + * It attempts to reduce, as much as possible, the number of queries + * involved. + * + * @param $table + * The name of the table to be loaded from. Data is expected to be in the + * schema to make all this work. + * @param $type + * A string to notify the loader what the argument is + * - all: load all items. This is the default. $args is unused. + * - names: $args will be an array of specific named objects to load. + * - conditions: $args will be a keyed array of conditions. The conditions + * must be in the schema for this table or errors will result. + * @param $args + * An array of arguments whose actual use is defined by the $type argument. + */ +function ctools_export_load_object($table, $type = 'all', $args = array()) { + $cache = &ctools_static(__FUNCTION__); + $cached_database = &ctools_static('ctools_export_load_object_all'); + + $schema = ctools_export_get_schema($table); + if (empty($schema)) { + return array(); + } + + $join_schemas = array(); + $export = $schema['export']; + + if (!isset($cache[$table])) { + $cache[$table] = array(); + } + + // If fetching all and cached all, we've done so and we are finished. + if ($type == 'all' && !empty($cached_database[$table])) { + return $cache[$table]; + } + + $return = array(); + + // Don't load anything we've already cached. + if ($type == 'names' && !empty($args)) { + foreach ($args as $id => $name) { + if (isset($cache[$table][$name])) { + $return[$name] = $cache[$table][$name]; + unset($args[$id]); + } + } + + // If nothing left to load, return the result. + if (empty($args)) { + return $return; + } + } + + // Build the query + $query = "SELECT * FROM {" . $table . "} t__0"; + $alias_count = 1; + if (!empty($schema['join'])) { + foreach ($schema['join'] as $join_key => $join) { + $join_schema = drupal_get_schema($join['table']); + if (!empty($join_schema)) { + $query .= ' INNER JOIN {' . $join['table'] . '} t__' . $alias_count . ' ON t__0.' . $join['left_key'] . ' = ' . 't__' . $alias_count . '.' . $join['right_key']; + $alias_count++; + $join_schemas[$join['table']] = $join_schema; + if (!empty($join['extra'])) { + $query .= ' ' . $join['extra']; + } + } + } + } + + $conditions = array(); + $query_args = array(); + + // If they passed in names, add them to the query. + if ($type == 'names') { + if (!isset($export['key in table'])) { + $conditions[] = "$export[key] IN (" . db_placeholders($args, $schema['fields'][$export['key']]['type']) . ")"; + } + else { + $conditions[] = "$export[key] IN (" . db_placeholders($args, $join_schemas[$export['key in table']]['fields'][$export['key']]['type']) . ")"; + } + $query_args = $args; + } + else if ($type == 'conditions') { + foreach ($args as $key => $value) { + if (isset($schema['fields'][$key])) { + $conditions[] = "$key = " . db_type_placeholder($schema['fields'][$key]['type']); + $query_args[] = $value; + } + } + } + + // Make a string out of the conditions. + if ($conditions) { + $query .= " WHERE " . implode(' AND ', $conditions); + } + + $result = db_query($query, $query_args); + + $status = variable_get($export['status'], array()); + // Unpack the results of the query onto objects and cache them. + while ($data = db_fetch_object($result)) { + if (isset($schema['export']['object factory']) && function_exists($schema['export']['object factory'])) { + $object = $schema['export']['object factory']($schema, $data); + } + else { + $object = _ctools_export_unpack_object($schema, $data, $export['object']); + } + $object->table = $table; + $object->{$export['export type string']} = t('Normal'); + $object->export_type = EXPORT_IN_DATABASE; + // Determine if default object is enabled or disabled. + if (isset($status[$object->{$export['key']}])) { + $object->disabled = $status[$object->{$export['key']}]; + } + + $cache[$table][$object->{$export['key']}] = $object; + if ($type == 'conditions') { + $return[$object->{$export['key']}] = $object; + } + } + + // Load subrecords. + if (isset($export['subrecords callback']) && function_exists($export['subrecords callback'])) { + $export['subrecords callback']($cache[$table]); + } + + if ($defaults = _ctools_export_get_defaults($table, $export)) { + + foreach ($defaults as $object) { + if ($type == 'conditions') { + // if this does not match all of our conditions, skip it. + foreach ($args as $key => $value) { + if (!isset($object->$key) || $object->$key != $value) { + continue 2; + } + } + } + else if ($type == 'names') { + if (!in_array($object->{$export['key']}, $args)) { + continue; + } + } + + // Determine if default object is enabled or disabled. + if (isset($status[$object->{$export['key']}])) { + $object->disabled = $status[$object->{$export['key']}]; + } + + if (!empty($cache[$table][$object->{$export['key']}])) { + $cache[$table][$object->{$export['key']}]->{$export['export type string']} = t('Overridden'); + $cache[$table][$object->{$export['key']}]->export_type |= EXPORT_IN_CODE; + if ($type == 'conditions') { + $return[$object->{$export['key']}] = $cache[$table][$object->{$export['key']}]; + } + } + else { + $object->{$export['export type string']} = t('Default'); + $object->export_type = EXPORT_IN_CODE; + $object->in_code_only = TRUE; + $object->table = $table; + + $cache[$table][$object->{$export['key']}] = $object; + if ($type == 'conditions') { + $return[$object->{$export['key']}] = $object; + } + } + } + } + + // If fetching all, we've done so and we are finished. + if ($type == 'all') { + $cached_database[$table] = TRUE; + return $cache[$table]; + } + + if ($type == 'names') { + foreach ($args as $name) { + if (isset($cache[$table][$name])) { + $return[$name] = $cache[$table][$name]; + } + } + } + + // For conditions, + return $return; +} + +/** + * Reset all static caches in ctools_export_load_object() or static caches for + * a given table in ctools_export_load_object(). + * + * @param $table + * String that is the name of a table. If not defined, all static caches in + * ctools_export_load_object() will be reset. + */ +function ctools_export_load_object_reset($table = NULL) { + // Reset plugin cache to make sure new include files are picked up. + ctools_include('plugins'); + ctools_get_plugins_reset(); + if (empty($table)) { + ctools_static_reset('ctools_export_load_object'); + ctools_static_reset('ctools_export_load_object_all'); + ctools_static_reset('_ctools_export_get_defaults'); + } + else { + $cache = &ctools_static('ctools_export_load_object'); + $cached_database = &ctools_static('ctools_export_load_object_all'); + $cached_defaults = &ctools_static('_ctools_export_get_defaults'); + unset($cache[$table]); + unset($cached_database[$table]); + unset($cached_defaults[$table]); + } +} + +/** + * Get the default version of an object, if it exists. + * + * This function doesn't care if an object is in the database or not and + * does not check. This means that export_type could appear to be incorrect, + * because a version could exist in the database. However, it's not + * incorrect for this function as it is *only* used for the default + * in code version. + */ +function ctools_get_default_object($table, $name) { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + + if (!$export['default hook']) { + return; + } + + // @todo add a method to load .inc files for this. + $defaults = _ctools_export_get_defaults($table, $export); + $status = variable_get($export['status'], array()); + + if (!isset($defaults[$name])) { + return; + } + + $object = $defaults[$name]; + + // Determine if default object is enabled or disabled. + if (isset($status[$object->{$export['key']}])) { + $object->disabled = $status[$object->{$export['key']}]; + } + + $object->{$export['export type string']} = t('Default'); + $object->export_type = EXPORT_IN_CODE; + $object->in_code_only = TRUE; + + return $object; +} + +/** + * Call the hook to get all default objects of the given type from the + * export. If configured properly, this could include loading up an API + * to get default objects. + */ +function _ctools_export_get_defaults($table, $export) { + $cache = &ctools_static(__FUNCTION__, array()); + + if (!isset($cache[$table])) { + $cache[$table] = array(); + + if ($export['default hook']) { + if (!empty($export['api'])) { + ctools_include('plugins'); + $info = ctools_plugin_api_include($export['api']['owner'], $export['api']['api'], + $export['api']['minimum_version'], $export['api']['current_version']); + $modules = array_keys($info); + } + else { + $modules = module_implements($export['default hook']); + } + + foreach ($modules as $module) { + $function = $module . '_' . $export['default hook']; + if (function_exists($function)) { + foreach ((array) $function($export) as $name => $object) { + // Record the module that provides this exportable. + if(is_object($object)) { + $object->export_module = $module; + } + + if (empty($export['api'])) { + $cache[$table][$name] = $object; + } + else { + // If version checking is enabled, ensure that the object can be used. + if (isset($object->api_version) && + $object->api_version >= $export['api']['minimum_version'] && + $object->api_version <= $export['api']['current_version']) { + $cache[$table][$name] = $object; + } + } + } + } + } + + drupal_alter($export['default hook'], $cache[$table]); + } + } + + return $cache[$table]; +} + +/** + * Unpack data loaded from the database onto an object. + * + * @param $schema + * The schema from drupal_get_schema(). + * @param $data + * The data as loaded by db_fetch_object(). + * @param $object + * If an object, data will be unpacked onto it. If a string + * an object of that type will be created. + */ +function _ctools_export_unpack_object($schema, $data, $object = 'stdClass') { + if (is_string($object)) { + if (class_exists($object)) { + $object = new $object; + } + else { + $object = new stdClass; + } + } + + // Go through our schema and build correlations. + foreach ($schema['fields'] as $field => $info) { + if (isset($data->$field)) { + $object->$field = empty($info['serialize']) ? $data->$field : unserialize(db_decode_blob($data->$field)); + } + else { + $data->$field = NULL; + } + } + + if (isset($schema['join'])) { + foreach ($schema['join'] as $join_key => $join) { + $join_schema = ctools_export_get_schema($join['table']); + if (!empty($join['load'])) { + foreach ($join['load'] as $field) { + $info = $join_schema['fields'][$field]; + $object->$field = empty($info['serialize']) ? $data->$field : unserialize(db_decode_blob($data->$field)); + } + } + } + } + + return $object; +} + +/** + * Unpack data loaded from the database onto an object. + * + * @param $table + * The name of the table this object represents. + * @param $data + * The data as loaded by db_fetch_object(). + */ +function ctools_export_unpack_object($table, $data) { + $schema = ctools_export_get_schema($table); + return _ctools_export_unpack_object($schema, $data, $schema['export']['object']); +} + +/** + * Export a field. + * + * This is a replacement for var_export(), allowing us to more nicely + * format exports. It will recurse down into arrays and will try to + * properly export bools when it can, though PHP has a hard time with + * this since they often end up as strings or ints. + */ +function ctools_var_export($var, $prefix = '') { + if (is_array($var)) { + if (empty($var)) { + $output = 'array()'; + } + else { + $output = "array(\n"; + foreach ($var as $key => $value) { + $output .= $prefix . " " . ctools_var_export($key) . " => " . ctools_var_export($value, $prefix . ' ') . ",\n"; + } + $output .= $prefix . ')'; + } + } + else if (is_object($var) && get_class($var) === 'stdClass') { + // var_export() will export stdClass objects using an undefined + // magic method __set_state() leaving the export broken. This + // workaround avoids this by casting the object as an array for + // export and casting it back to an object when evaluated. + $output = '(object) ' . ctools_var_export((array) $var, $prefix); + } + else if (is_bool($var)) { + $output = $var ? 'TRUE' : 'FALSE'; + } + else { + $output = var_export($var, TRUE); + } + + return $output; +} + +/** + * Export an object into code. + */ +function ctools_export_object($table, $object, $indent = '', $identifier = NULL, $additions = array(), $additions2 = array()) { + $schema = ctools_export_get_schema($table); + if (!isset($identifier)) { + $identifier = $schema['export']['identifier']; + } + + $output = $indent . '$' . $identifier . ' = new ' . get_class($object) . ";\n"; + + if ($schema['export']['can disable']) { + $output .= $indent . '$' . $identifier . '->disabled = FALSE; /* Edit this to true to make a default ' . $identifier . ' disabled initially */' . "\n"; + } + if (!empty($schema['export']['api']['current_version'])) { + $output .= $indent . '$' . $identifier . '->api_version = ' . $schema['export']['api']['current_version'] . ";\n"; + } + + // Put top additions here: + foreach ($additions as $field => $value) { + $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n"; + } + + $fields = $schema['fields']; + if (!empty($schema['join'])) { + foreach ($schema['join'] as $join) { + if (!empty($join['load'])) { + foreach ($join['load'] as $join_field) { + $fields[$join_field] = $join['fields'][$join_field]; + } + } + } + } + + // Go through our schema and joined tables and build correlations. + foreach ($fields as $field => $info) { + if (!empty($info['no export'])) { + continue; + } + if (!isset($object->$field)) { + if (isset($info['default'])) { + $object->$field = $info['default']; + } + else { + $object->$field = ''; + } + } + + // Note: This is the *field* export callback, not the table one! + if (!empty($info['export callback']) && function_exists($info['export callback'])) { + $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . $info['export callback']($object, $field, $object->$field, $indent) . ";\n"; + } + else { + $value = $object->$field; + if ($info['type'] == 'int') { + $value = (isset($info['size']) && $info['size'] == 'tiny') ? (bool) $value : (int) $value; + } + + $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n"; + } + } + + // And bottom additions here + foreach ($additions2 as $field => $value) { + $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n"; + } + + return $output; +} + +/** + * Get the schema for a given table. + * + * This looks for data the export subsystem needs and applies defaults so + * that it's easily available. + */ +function ctools_export_get_schema($table) { + $cache = &ctools_static(__FUNCTION__); + if (empty($cache[$table])) { + $schema = drupal_get_schema($table); + + if (!isset($schema['export'])) { + return array(); + } + + if (empty($schema['module'])) { + return array(); + } + + // Add some defaults + $schema['export'] += array( + 'key' => 'name', + 'key name' => 'Name', + 'object' => 'stdClass', + 'status' => 'default_' . $table, + 'default hook' => 'default_' . $table, + 'can disable' => TRUE, + 'identifier' => $table, + 'primary key' => !empty($schema['primary key']) ? $schema['primary key'][0] : '', + 'bulk export' => TRUE, + 'list callback' => "$schema[module]_{$table}_list", + 'to hook code callback' => "$schema[module]_{$table}_to_hook_code", + 'export type string' => 'type', + ); + + // If the export definition doesn't have the "primary key" then the CRUD + // save callback won't work. + if (empty($schema['export']['primary key']) && user_access('administer site configuration')) { + drupal_set_message(t('The export definition of @table is missing the "primary key" property.', array('@table' => $table)), 'error'); + } + + // Notes: + // The following callbacks may be defined to override default behavior + // when using CRUD functions: + // + // create callback + // load callback + // load all callback + // save callback + // delete callback + // export callback + // import callback + // + // See the appropriate ctools_export_crud function for details on what + // arguments these callbacks should accept. Please do not call these + // directly, always use the ctools_export_crud_* wrappers to ensure + // that default implementations are honored. + $cache[$table] = $schema; + } + + return $cache[$table]; +} + +/** + * Gets the schemas for all tables with ctools object metadata. + */ +function ctools_export_get_schemas($for_export = FALSE) { + static $export_tables; + if (is_null($export_tables)) { + $export_tables = array(); + $schemas = drupal_get_schema(); + foreach ($schemas as $table => $schema) { + if (!isset($schema['export'])) { + unset($schemas[$table]); + continue; + } + $export_tables[$table] = ctools_export_get_schema($table); + } + } + return $for_export ? array_filter($export_tables, '_ctools_export_filter_export_tables') : $export_tables; +} + +function _ctools_export_filter_export_tables($schema) { + return !empty($schema['export']['bulk export']); +} + +function ctools_export_get_schemas_by_module($modules = array(), $for_export = FALSE) { + $export_tables = array(); + $list = ctools_export_get_schemas($for_export); + foreach ($list as $table => $schema) { + $export_tables[$schema['module']][$table] = $schema; + } + return empty($modules) ? $export_tables : array_keys($export_tables, $modules); +} + +/** + * Set the status of a default $object as a variable. + * + * The status, in this case, is whether or not it is 'disabled'. + * This function does not check to make sure $object actually + * exists. + */ +function ctools_export_set_status($table, $name, $new_status = TRUE) { + $schema = ctools_export_get_schema($table); + $status = variable_get($schema['export']['status'], array()); + + $status[$name] = $new_status; + variable_set($schema['export']['status'], $status); +} + +/** + * Set the status of a default $object as a variable. + * + * This is more efficient than ctools_export_set_status because it + * will actually unset the variable entirely if it's not necessary, + * this saving a bit of space. + */ +function ctools_export_set_object_status($object, $new_status = TRUE) { + $table = $object->table; + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + $status = variable_get($schema['export']['status'], array()); + + // Compare + if (!$new_status && $object->export_type & EXPORT_IN_DATABASE) { + unset($status[$object->{$export['key']}]); + } + else { + $status[$object->{$export['key']}] = $new_status; + } + + variable_set($schema['export']['status'], $status); +} + +/** + * Provide a form for displaying an export. + * + * This is a simple form that should be invoked like this: + * @code + * $output = drupal_get_form('ctools_export_form', $code, $object_title); + * @endcode + */ +function ctools_export_form(&$form_state, $code, $title = '') { + $lines = substr_count($code, "\n"); + $form['code'] = array( + '#type' => 'textarea', + '#title' => $title, + '#default_value' => $code, + '#rows' => $lines, + ); + + return $form; +} + +/** + * Create a new object based upon schema values. + * + * Because 'default' has ambiguous meaning on some fields, we will actually + * use 'object default' to fill in default values if default is not set + * That's a little safer to use as it won't cause weird database default + * situations. + */ +function ctools_export_new_object($table, $set_defaults = TRUE) { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + + $object = new $export['object']; + foreach ($schema['fields'] as $field => $info) { + if (isset($info['object default'])) { + $object->$field = $info['object default']; + } + else if (isset($info['default'])) { + $object->$field = $info['default']; + } + else { + $object->$field = NULL; + } + } + + if ($set_defaults) { + // Set some defaults so this data always exists. + // We don't set the export_type property here, as this object is not saved + // yet. We do give it NULL so we don't generate notices trying to read it. + $object->export_type = NULL; + $object->{$export['export type string']} = t('Local'); + } + return $object; +} + +/** + * Convert a group of objects to code based upon input and return this as a larger + * export. + */ +function ctools_export_to_hook_code(&$code, $table, $names = array(), $name = 'foo') { + $schema = ctools_export_get_schema($table); + $export = $schema['export']; + // Use the schema-specified function for generating hook code, if one exists + if (function_exists($export['to hook code callback'])) { + $output = $export['to hook code callback']($names, $name); + } + // Otherwise, the following code generates basic hook code + else { + $output = ctools_export_default_to_hook_code($schema, $table, $names, $name); + } + + if (!empty($output)) { + if (isset($export['api'])) { + if (isset($code[$export['api']['owner']][$export['api']['api']]['version'])) { + $code[$export['api']['owner']][$export['api']['api']]['version'] = max($code[$export['api']['owner']][$export['api']['api']]['version'], $export['api']['minimum_version']); + } + else { + $code[$export['api']['owner']][$export['api']['api']]['version'] = $export['api']['minimum_version']; + $code[$export['api']['owner']][$export['api']['api']]['code'] = ''; + } + $code[$export['api']['owner']][$export['api']['api']]['code'] .= $output; + } + else { + if (empty($code['general'])) { + $code['general'] = ''; + } + $code['general'] .= $output; + } + } +} + +/** + * Default function to export objects to code. + * + * Note that if your module provides a 'to hook code callback' then it will + * receive only $names and $name as arguments. Your module is presumed to + * already know the rest. + */ +function ctools_export_default_to_hook_code($schema, $table, $names, $name) { + $export = $schema['export']; + $output = ''; + $objects = ctools_export_load_object($table, 'names', $names); + if ($objects) { + $output = "/**\n"; + $output .= " * Implements hook_{$export['default hook']}().\n"; + $output .= " */\n"; + $output .= "function " . $name . "_{$export['default hook']}() {\n"; + $output .= " \${$export['identifier']}s = array();\n\n"; + foreach ($objects as $object) { + $output .= ctools_export_crud_export($table, $object, ' '); + $output .= " \${$export['identifier']}s['" . check_plain($object->$export['key']) . "'] = \${$export['identifier']};\n\n"; + } + $output .= " return \${$export['identifier']}s;\n"; + $output .= "}\n"; + } + + return $output; +} +/** + * Default function for listing bulk exportable objects. + */ +function ctools_export_default_list($table, $schema) { + $list = array(); + + $items = ctools_export_crud_load_all($table); + $export_key = $schema['export']['key']; + + foreach ($items as $item) { + // Try a couple of possible obvious title keys: + if (!empty($item->admin_title)) { + $string = "$item->admin_title (" . $item->$export_key . ")"; + } + elseif (!empty($item->title)) { + $string = "$item->title (" . $item->$export_key . ")"; + } + else { + $string = $item->$export_key; + } + $list[$item->$export_key] = check_plain($string); + } + return $list; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/form.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/form.inc new file mode 100644 index 0000000000000000000000000000000000000000..b90f129dc35492f7a74ce9d9d234a9d5c7038807 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/form.inc @@ -0,0 +1,333 @@ +<?php + +/** + * @file + * CTools' replacements for Drupal's form functions. + * + * Primarily, ctools_build_form is meant to be a replacement for drupal_get_form(). + * + * Instead of sending arguments through to the form builder, a form state array + * is passed through. This form_state can contain any arguments needed, and it can + * also be used to return data to the calling function. + * + * This can allow cleaner separation of the form from the storage mechanism. + */ + +/** + * Build a form, similar to drupal_get_form(). However, arguments + * to the form builder are not sent through. Instead, the $form_state + * can be given all the necessary data to fully utilize the form. + */ +function ctools_build_form($form_id, &$form_state) { + // Ensure that we have some defaults. + + // These are defaults only; if already set they will not be overridden. + $form_state += array('storage' => NULL, 'submitted' => FALSE, 'input' => $_POST, 'method' => 'post'); + + $args = isset($form_state['args']) ? $form_state['args'] : array(); + $cacheable = FALSE; + + if (isset($_SESSION['batch_form_state'])) { + // We've been redirected here after a batch processing : the form has + // already been processed, so we grab the post-process $form_state value + // and move on to form display. See _batch_finished() function. + $form_state = $_SESSION['batch_form_state']; + unset($_SESSION['batch_form_state']); + } + else { + // If the incoming $form_state['input'] contains a form_build_id, we'll check the + // cache for a copy of the form in question. If it's there, we don't + // have to rebuild the form to proceed. In addition, if there is stored + // form_state data from a previous step, we'll retrieve it so it can + // be passed on to the form processing code. + if (isset($form_state['input']['form_id']) && $form_state['input']['form_id'] == $form_id && !empty($form_state['input']['form_build_id'])) { + $form_build_id = $form_state['input']['form_build_id']; + $form = form_get_cache($form_build_id, $form_state); + if (!empty($form['#no_cache']) || empty($form)) { + unset($form); + } + } + + // If the previous bit of code didn't result in a populated $form + // object, we're hitting the form for the first time and we need + // to build it from scratch. + if (!isset($form)) { + $form_state['post'] = $form_state['input']; + // This allows us to do some interesting form embedding stuff without + // messing up the form IDs too badly. + if (isset($form_state['wrapper callback']) && function_exists($form_state['wrapper callback'])) { + // If there is a wrapper callback, we do not use drupal_retrieve_form. + // Instead, we call $form_id builder function directly. This means the args + // are *different* for forms used this way, which may not be ideal but + // is necessary right now. + $form = array(); + $form_state['wrapper callback']($form, $form_state); + if (function_exists($form_id)) { + $form_id($form, $form_state); + } + } + else { + // Use a copy of the function's arguments for manipulation + $args_temp = $args; + array_unshift($args_temp, 'placeholder'); + $args_temp[0] = &$form_state; // replaces the placeholder. + array_unshift($args_temp, $form_id); + + $form = call_user_func_array('drupal_retrieve_form', $args_temp); + } + + $form_build_id = 'form-' . md5(mt_rand()); + $form['#build_id'] = $form_build_id; + + + if ($form_state['method'] == 'get' && !isset($form['#method'])) { + $form['#method'] = 'get'; + } + + drupal_prepare_form($form_id, $form, $form_state); + // Store a copy of the unprocessed form for caching and indicate that it + // is cacheable if #cache will be set. + $original_form = $form; + $cacheable = TRUE; + unset($form_state['post']); + } + $form['#post'] = $form_state['input']; + + // Now that we know we have a form, we'll process it (validating, + // submitting, and handling the results returned by its submission + // handlers. Submit handlers accumulate data in the form_state by + // altering the $form_state variable, which is passed into them by + // reference. + ctools_process_form($form_id, $form, $form_state); + // If we were told not to redirect, but not told to re-render, return + // here. + if (!empty($form_state['executed']) && empty($form_state['rerender'])) { + return; + } + if ($cacheable && !empty($form['#cache']) && empty($form['#no_cache'])) { + // Caching is done past drupal_process_form so #process callbacks can + // set #cache. By not sending the form state, we avoid storing + // $form_state['storage']. + form_set_cache($form_build_id, $original_form, NULL); + } + } + + // Most simple, single-step forms will be finished by this point -- + // drupal_process_form() usually redirects to another page (or to + // a 'fresh' copy of the form) once processing is complete. If one + // of the form's handlers has set $form_state['redirect'] to FALSE, + // the form will simply be re-rendered with the values still in its + // fields. + // + // If $form_state['storage'] or $form_state['rebuild'] have been + // set by any submit or validate handlers, however, we know that + // we're in a complex multi-part process of some sort and the form's + // workflow is NOT complete. We need to construct a fresh copy of + // the form, passing in the latest $form_state in addition to any + // other variables passed into drupal_get_form(). + // + // If this function is being used to perform an '#ahah' callback + // to rebuild some or all of a ctools wizard form step, be sure that + // $form_state['wrapper callback'], $form_state['form_info'], + // $form_state['step'], $form_state['no_redirect'], and $form_state['rebuild'] + // are properly set. + + if (!empty($form_state['rebuild']) || !empty($form_state['storage'])) { + $form = ctools_rebuild_form($form_id, $form_state, $args, $form_build_id); + } + + // If whoever is calling this wants the $form array (so that it can render it + // another way, for example) then return it. + if (!empty($form_state['want form'])) { + return $form; + } + + // Do not render certain items if requested not to: + if (!empty($form_state['drop tokens'])) { + unset($form['#id']); + unset($form['#build_id']); + unset($form['#token']); + unset($form['form_token']); + } + // If we haven't redirected to a new location by now, we want to + // render whatever form array is currently in hand. + // Do not render certain items if requested not to: + if (!empty($form_state['drop tokens'])) { + unset($form['form_id']); + unset($form['form_build_id']); + unset($form['form_token']); + } + return drupal_render_form($form_id, $form); +} + +/** + * ctools' replacement of drupal_rebuild_form. + * + * This change merely respects a form's wishes not to be cached. + */ +function ctools_rebuild_form($form_id, &$form_state, $args, $form_build_id = NULL) { + // Remove the first argument. This is $form_id.when called from + // drupal_get_form and the original $form_state when called from some AHAH + // callback. Neither is needed. After that, put in the current state. + array_unshift($args, 'placeholder'); + $args[0] = &$form_state; // Replaces placeholder. + // And the form_id. + array_unshift($args, $form_id); + + if (isset($form_state['wrapper callback']) && function_exists($form_state['wrapper callback'])) { + // If there is a wrapper callback, we do not use drupal_retrieve_form. + // Instead, we call $form_id builder function directly. This means the args + // are *different* for forms used this way, which may not be ideal but + // is necessary right now. + $form = array(); + $form_state['wrapper callback']($form, $form_state); + if (function_exists($form_id)) { + $form_id($form, $form_state); + } + } + else { + $form = call_user_func_array('drupal_retrieve_form', $args); + } + + if (!isset($form_build_id)) { + // We need a new build_id for the new version of the form. + $form_build_id = 'form-' . md5(mt_rand()); + } + $form['#build_id'] = $form_build_id; + // Flush form ID element cache because we may be rebuilding + // a form in a way that Drupal's FAPI isn't used to which + // causes unnecessary form ID changes. + form_clean_id(NULL, TRUE); + drupal_prepare_form($form_id, $form, $form_state); + + if (empty($form['#no_cache'])) { + // Now, we cache the form structure so it can be retrieved later for + // validation. If $form_state['storage'] is populated, we'll also cache + // it so that it can be used to resume complex multi-step processes. + form_set_cache($form_build_id, $form, $form_state); + } + + // Originally this called drupal_process_form, but all that happens there + // is form_builder and then submission; and the rebuilt form is not + // allowed to submit. Therefore, just do this: + $form['#post'] = $form_state['input']; + $form = form_builder($form_id, $form, $form_state); + + return $form; +} + +/** + * ctools' replacement for drupal_process_form that accepts commands + * not to redirect, as well as forcing processing of 'get' method forms. + */ +function ctools_process_form($form_id, &$form, &$form_state) { + // submitting, and handling the results returned by its submission + // handlers. Submit handlers accumulate data in the form_state by + // altering the $form_state variable, which is passed into them by + // reference. + $form_state['values'] = array(); + + // With $_GET, these forms are always submitted. + if ($form_state['method'] == 'get') { + if (!isset($form['#post']['form_build_id'])) { + $form['#post']['form_build_id'] = $form['#build_id']; + } + if (!isset($form['#post']['form_id'])) { + $form['#post']['form_id'] = $form_id; + } + if (!isset($form['#post']['form_token']) && isset($form['#token'])) { + $form['#post']['form_token'] = drupal_get_token($form['#token']); + } + } + + $form = form_builder($form_id, $form, $form_state); + // Only process the form if it is programmed or the form_id coming + // from the POST data is set and matches the current form_id. + + if ((!empty($form['#programmed'])) || (!empty($form['#post']) && (isset($form['#post']['form_id']) && ($form['#post']['form_id'] == $form_id)))) { + ctools_validate_form($form_id, $form, $form_state); + + // form_clean_id() maintains a cache of element IDs it has seen, + // so it can prevent duplicates. We want to be sure we reset that + // cache when a form is processed, so scenerios that result in + // the form being built behind the scenes and again for the + // browser don't increment all the element IDs needlessly. + form_clean_id(NULL, TRUE); + + if ((!empty($form_state['submitted'])) && !form_get_errors() && empty($form_state['rebuild'])) { + $form_state['redirect'] = NULL; + form_execute_handlers('submit', $form, $form_state); + + // We'll clear out the cached copies of the form and its stored data + // here, as we've finished with them. The in-memory copies are still + // here, though. + if (variable_get('cache', CACHE_DISABLED) == CACHE_DISABLED && !empty($form_state['values']['form_build_id'])) { + cache_clear_all('form_' . $form_state['values']['form_build_id'], 'cache_form'); + cache_clear_all('storage_' . $form_state['values']['form_build_id'], 'cache_form'); + } + + // If batches were set in the submit handlers, we process them now, + // possibly ending execution. We make sure we do not react to the batch + // that is already being processed (if a batch operation performs a + // drupal_execute). + if ($batch = &batch_get() && !isset($batch['current_set'])) { + // The batch uses its own copies of $form and $form_state for + // late execution of submit handers and post-batch redirection. + $batch['form'] = $form; + $batch['form_state'] = $form_state; + $batch['progressive'] = !$form['#programmed']; + batch_process(); + // Execution continues only for programmatic forms. + // For 'regular' forms, we get redirected to the batch processing + // page. Form redirection will be handled in _batch_finished(), + // after the batch is processed. + } + + // If no submit handlers have populated the $form_state['storage'] + // bundle, and the $form_state['rebuild'] flag has not been set, + // we're finished and should redirect to a new destination page + // if one has been set (and a fresh, unpopulated copy of the form + // if one hasn't). If the form was called by drupal_execute(), + // however, we'll skip this and let the calling function examine + // the resulting $form_state bundle itself. + if (!$form['#programmed'] && empty($form_state['rebuild']) && empty($form_state['storage'])) { + if (!empty($form_state['no_redirect'])) { + $form_state['executed'] = TRUE; + } + else { + drupal_redirect_form($form, $form_state['redirect']); + } + } + } + } +} + +/** + * The original version of drupal_validate_form does not have an override for + * the static check to only validate a form id once. Unfortunately, we need + * to be able to override this. + */ +function ctools_validate_form($form_id, $form, &$form_state) { + static $validated_forms = array(); + + if (isset($validated_forms[$form_id]) && empty($form_state['must_validate'])) { + return; + } + + // If the session token was set by drupal_prepare_form(), ensure that it + // matches the current user's session. + if (isset($form['#token'])) { + if (!drupal_valid_token($form_state['values']['form_token'], $form['#token'])) { + // Setting this error will cause the form to fail validation. + form_set_error('form_token', t('Validation error, please try again. If this error persists, please contact the site administrator.')); + } + } + + if (!empty($form_state['clicked_button']['#skip validation'])) { + return; + } + + _form_validate($form, $form_state, $form_id); + $validated_forms[$form_id] = TRUE; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/jump-menu.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/jump-menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..c5583cc9682e8212d8a1e86e970229e10b9c305f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/jump-menu.inc @@ -0,0 +1,120 @@ +<?php + +/** + * @file + * Provides a simple "jump menu". + * + * A jump menu is a select box and an optional 'go' button which can be removed + * if javascript is in use. Each item is keyed to the href that the button + * should go to. With javascript, the page is immediately redirected. Without + * javascript, the form is submitted and a drupal_goto() is given. + * + */ + +/** + * Generate a jump menu form. + * + * This can either be used with drupal_get_form() or directly added to a + * form. The button provides its own submit handler so by default, other + * submit handlers will not be called. + * + * One note: Do not use #tree = TRUE or it will be unable to find the + * proper value. + * + * @code + * ctools_include('jump-menu'); + * $output = drupal_get_form('ctools_jump_menu', $targets, $options); + * @endcode + * + * @param $select + * An array suitable for use as the #options. The keys will be the direct + * URLs that will be jumped to, so you absolutely must encode these using + * url() in order for them to work reliably. + * + * @param $options + * $options may be an array with the following options: + * - 'title': The text to display for the #title attribute. + * - 'description': The text to display for the #description attribute. + * - 'default_value': The text to display for the #default_value attribute. + * - 'hide': If TRUE the go button will be set to hide via javascript and + * will submit on change. + * - 'button': The text to display on the button. + * - 'image': If set, an image button will be used instead, and the image + * set to this. + * - 'inline': If set to TRUE (default) the display will be forced inline. + */ +function ctools_jump_menu($form_state, $select, $options = array()) { + $options += array( + 'button' => t('Go'), + 'choose' => t('- Choose -'), + 'inline' => TRUE, + 'hide' => TRUE, + ); + + ctools_add_js('jump-menu'); + + if (!empty($options['choose'])) { + $select = array('' => $options['choose']) + $select; + } + + $form['jump'] = array( + '#type' => 'select', + '#options' => $select, + '#attributes' => array( + 'class' => 'ctools-jump-menu-select', + ), + ); + + if (!empty($options['title'])) { + $form['jump']['#title'] = $options['title']; + } + + if (!empty($options['description'])) { + $form['jump']['#description'] = $options['description']; + } + + if (!empty($options['default_value'])) { + $form['jump']['#default_value'] = $options['default_value']; + } + + if (isset($options['image'])) { + $form['go'] = array( + '#type' => 'image_button', + '#src' => $options['image'], + '#submit' => array('ctools_jump_menu_submit'), + '#attributes' => array( + 'class' => 'ctools-jump-menu-button', + ), + ); + } + else { + $form['go'] = array( + '#type' => 'submit', + '#value' => $options['button'], + '#attributes' => array( + 'class' => 'ctools-jump-menu-button', + ), + ); + } + + if ($options['inline']) { + $form['jump']['#prefix'] = '<div class="container-inline">'; + $form['go']['#suffix'] = '</div>'; + } + + if ($options['hide']) { + $form['jump']['#attributes']['class'] .= ' ctools-jump-menu-change'; + $form['go']['#attributes']['class'] .= ' ctools-jump-menu-hide'; + } + + return $form; +} + +/** + * Submit handler for the jump menu. + * + * This is normally only invoked upon submit without javascript enabled. + */ +function ctools_jump_menu_submit($form, &$form_state) { + $form_state['redirect'] = $form_state['values']['jump']; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/math-expr.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/math-expr.inc new file mode 100644 index 0000000000000000000000000000000000000000..b4b7fb73088324bc62ba11195ea151e31658f9b7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/math-expr.inc @@ -0,0 +1,387 @@ +<?php + +/* +================================================================================ + +ctools_math_expr - PHP Class to safely evaluate math expressions +Copyright (C) 2005 Miles Kaufmann <http://www.twmagic.com/> + +================================================================================ + +NAME + ctools_math_expr - safely evaluate math expressions + +SYNOPSIS + include('ctools_math_expr.class.php'); + $m = new ctools_math_expr; + // basic evaluation: + $result = $m->evaluate('2+2'); + // supports: order of operation; parentheses; negation; built-in functions + $result = $m->evaluate('-8(5/2)^2*(1-sqrt(4))-8'); + // create your own variables + $m->evaluate('a = e^(ln(pi))'); + // or functions + $m->evaluate('f(x,y) = x^2 + y^2 - 2x*y + 1'); + // and then use them + $result = $m->evaluate('3*f(42,a)'); + +DESCRIPTION + Use the ctools_math_expr class when you want to evaluate mathematical expressions + from untrusted sources. You can define your own variables and functions, + which are stored in the object. Try it, it's fun! + +METHODS + $m->evalute($expr) + Evaluates the expression and returns the result. If an error occurs, + prints a warning and returns false. If $expr is a function assignment, + returns true on success. + + $m->e($expr) + A synonym for $m->evaluate(). + + $m->vars() + Returns an associative array of all user-defined variables and values. + + $m->funcs() + Returns an array of all user-defined functions. + +PARAMETERS + $m->suppress_errors + Set to true to turn off warnings when evaluating expressions + + $m->last_error + If the last evaluation failed, contains a string describing the error. + (Useful when suppress_errors is on). + +AUTHOR INFORMATION + Copyright 2005, Miles Kaufmann. + +LICENSE + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1 Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +*/ + +class ctools_math_expr { + var $suppress_errors = false; + var $last_error = null; + + var $v = array('e'=>2.71,'pi'=>3.14); // variables (and constants) + var $f = array(); // user-defined functions + var $vb = array('e', 'pi'); // constants + var $fb = array( // built-in functions + 'sin','sinh','arcsin','asin','arcsinh','asinh', + 'cos','cosh','arccos','acos','arccosh','acosh', + 'tan','tanh','arctan','atan','arctanh','atanh', + 'sqrt','abs','ln','log', + 'time', 'ceil', 'floor', 'min', 'max', 'round'); + + function ctools_math_expr() { + // make the variables a little more accurate + $this->v['pi'] = pi(); + $this->v['e'] = exp(1); + drupal_alter('ctools_math_expression_functions', $this->fb); + } + + function e($expr) { + return $this->evaluate($expr); + } + + function evaluate($expr) { + $this->last_error = null; + $expr = trim($expr); + if (substr($expr, -1, 1) == ';') $expr = substr($expr, 0, strlen($expr)-1); // strip semicolons at the end + //=============== + // is it a variable assignment? + if (preg_match('/^\s*([a-z]\w*)\s*=\s*(.+)$/', $expr, $matches)) { + if (in_array($matches[1], $this->vb)) { // make sure we're not assigning to a constant + return $this->trigger("cannot assign to constant '$matches[1]'"); + } + if (($tmp = $this->pfx($this->nfx($matches[2]))) === false) return false; // get the result and make sure it's good + $this->v[$matches[1]] = $tmp; // if so, stick it in the variable array + return $this->v[$matches[1]]; // and return the resulting value + //=============== + // is it a function assignment? + } elseif (preg_match('/^\s*([a-z]\w*)\s*\(\s*([a-z]\w*(?:\s*,\s*[a-z]\w*)*)\s*\)\s*=\s*(.+)$/', $expr, $matches)) { + $fnn = $matches[1]; // get the function name + if (in_array($matches[1], $this->fb)) { // make sure it isn't built in + return $this->trigger("cannot redefine built-in function '$matches[1]()'"); + } + $args = explode(",", preg_replace("/\s+/", "", $matches[2])); // get the arguments + if (($stack = $this->nfx($matches[3])) === false) return false; // see if it can be converted to postfix + for ($i = 0; $i<count($stack); $i++) { // freeze the state of the non-argument variables + $token = $stack[$i]; + if (preg_match('/^[a-z]\w*$/', $token) and !in_array($token, $args)) { + if (array_key_exists($token, $this->v)) { + $stack[$i] = $this->v[$token]; + } else { + return $this->trigger("undefined variable '$token' in function definition"); + } + } + } + $this->f[$fnn] = array('args'=>$args, 'func'=>$stack); + return true; + //=============== + } else { + return $this->pfx($this->nfx($expr)); // straight up evaluation, woo + } + } + + function vars() { + $output = $this->v; + unset($output['pi']); + unset($output['e']); + return $output; + } + + function funcs() { + $output = array(); + foreach ($this->f as $fnn=>$dat) + $output[] = $fnn . '(' . implode(',', $dat['args']) . ')'; + return $output; + } + + //===================== HERE BE INTERNAL METHODS ====================\\ + + // Convert infix to postfix notation + function nfx($expr) { + + $index = 0; + $stack = new ctools_math_expr_stack; + $output = array(); // postfix form of expression, to be passed to pfx() + $expr = trim(strtolower($expr)); + + $ops = array('+', '-', '*', '/', '^', '_'); + $ops_r = array('+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1); // right-associative operator? + $ops_p = array('+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2); // operator precedence + + $expecting_op = false; // we use this in syntax-checking the expression + // and determining when a - is a negation + + if (preg_match("/[^\w\s+*^\/()\.,-]/", $expr, $matches)) { // make sure the characters are all good + return $this->trigger("illegal character '{$matches[0]}'"); + } + + while(1) { // 1 Infinite Loop ;) + $op = substr($expr, $index, 1); // get the first character at the current index + // find out if we're currently at the beginning of a number/variable/function/parenthesis/operand + $ex = preg_match('/^([a-z]\w*\(?|\d+(?:\.\d*)?|\.\d+|\()/', substr($expr, $index), $match); + //=============== + if ($op == '-' and !$expecting_op) { // is it a negation instead of a minus? + $stack->push('_'); // put a negation on the stack + $index++; + } elseif ($op == '_') { // we have to explicitly deny this, because it's legal on the stack + return $this->trigger("illegal character '_'"); // but not in the input expression + //=============== + } elseif ((in_array($op, $ops) or $ex) and $expecting_op) { // are we putting an operator on the stack? + if ($ex) { // are we expecting an operator but have a number/variable/function/opening parethesis? + $op = '*'; $index--; // it's an implicit multiplication + } + // heart of the algorithm: + while($stack->count > 0 and ($o2 = $stack->last()) and in_array($o2, $ops) and ($ops_r[$op] ? $ops_p[$op] < $ops_p[$o2] : $ops_p[$op] <= $ops_p[$o2])) { + $output[] = $stack->pop(); // pop stuff off the stack into the output + } + // many thanks: http://en.wikipedia.org/wiki/Reverse_Polish_notation#The_algorithm_in_detail + $stack->push($op); // finally put OUR operator onto the stack + $index++; + $expecting_op = false; + //=============== + } elseif ($op == ')' and $expecting_op) { // ready to close a parenthesis? + while (($o2 = $stack->pop()) != '(') { // pop off the stack back to the last ( + if (is_null($o2)) return $this->trigger("unexpected ')'"); + else $output[] = $o2; + } + if (preg_match("/^([a-z]\w*)\($/", $stack->last(2), $matches)) { // did we just close a function? + $fnn = $matches[1]; // get the function name + $arg_count = $stack->pop(); // see how many arguments there were (cleverly stored on the stack, thank you) + $output[] = $stack->pop(); // pop the function and push onto the output + if (in_array($fnn, $this->fb)) { // check the argument count + if($arg_count > 1) + return $this->trigger("too many arguments ($arg_count given, 1 expected)"); + } elseif (array_key_exists($fnn, $this->f)) { + if ($arg_count != count($this->f[$fnn]['args'])) + return $this->trigger("wrong number of arguments ($arg_count given, " . count($this->f[$fnn]['args']) . " expected)"); + } else { // did we somehow push a non-function on the stack? this should never happen + return $this->trigger("internal error"); + } + } + $index++; + //=============== + } elseif ($op == ',' and $expecting_op) { // did we just finish a function argument? + while (($o2 = $stack->pop()) != '(') { + if (is_null($o2)) return $this->trigger("unexpected ','"); // oops, never had a ( + else $output[] = $o2; // pop the argument expression stuff and push onto the output + } + // make sure there was a function + if (!preg_match("/^([a-z]\w*)\($/", $stack->last(2), $matches)) + return $this->trigger("unexpected ','"); + $stack->push($stack->pop()+1); // increment the argument count + $stack->push('('); // put the ( back on, we'll need to pop back to it again + $index++; + $expecting_op = false; + //=============== + } elseif ($op == '(' and !$expecting_op) { + $stack->push('('); // that was easy + $index++; + $allow_neg = true; + //=============== + } elseif ($ex and !$expecting_op) { // do we now have a function/variable/number? + $expecting_op = true; + $val = $match[1]; + if (preg_match("/^([a-z]\w*)\($/", $val, $matches)) { // may be func, or variable w/ implicit multiplication against parentheses... + if (in_array($matches[1], $this->fb) or array_key_exists($matches[1], $this->f)) { // it's a func + $stack->push($val); + $stack->push(1); + $stack->push('('); + $expecting_op = false; + } else { // it's a var w/ implicit multiplication + $val = $matches[1]; + $output[] = $val; + } + } else { // it's a plain old var or num + $output[] = $val; + } + $index += strlen($val); + //=============== + } elseif ($op == ')') { // miscellaneous error checking + return $this->trigger("unexpected ')'"); + } elseif (in_array($op, $ops) and !$expecting_op) { + return $this->trigger("unexpected operator '$op'"); + } else { // I don't even want to know what you did to get here + return $this->trigger("an unexpected error occured"); + } + if ($index == strlen($expr)) { + if (in_array($op, $ops)) { // did we end with an operator? bad. + return $this->trigger("operator '$op' lacks operand"); + } else { + break; + } + } + while (substr($expr, $index, 1) == ' ') { // step the index past whitespace (pretty much turns whitespace + $index++; // into implicit multiplication if no operator is there) + } + + } + while (!is_null($op = $stack->pop())) { // pop everything off the stack and push onto output + if ($op == '(') return $this->trigger("expecting ')'"); // if there are (s on the stack, ()s were unbalanced + $output[] = $op; + } + return $output; + } + + // evaluate postfix notation + function pfx($tokens, $vars = array()) { + + if ($tokens == false) return false; + + $stack = new ctools_math_expr_stack; + + foreach ($tokens as $token) { // nice and easy + // if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on + if (in_array($token, array('+', '-', '*', '/', '^'))) { + if (is_null($op2 = $stack->pop())) return $this->trigger("internal error"); + if (is_null($op1 = $stack->pop())) return $this->trigger("internal error"); + switch ($token) { + case '+': + $stack->push($op1+$op2); break; + case '-': + $stack->push($op1-$op2); break; + case '*': + $stack->push($op1*$op2); break; + case '/': + if ($op2 == 0) return $this->trigger("division by zero"); + $stack->push($op1/$op2); break; + case '^': + $stack->push(pow($op1, $op2)); break; + } + // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on + } elseif ($token == "_") { + $stack->push(-1*$stack->pop()); + // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on + } elseif (preg_match("/^([a-z]\w*)\($/", $token, $matches)) { // it's a function! + $fnn = $matches[1]; + if (in_array($fnn, $this->fb)) { // built-in function: + if (is_null($op1 = $stack->pop())) return $this->trigger("internal error"); + $fnn = preg_replace("/^arc/", "a", $fnn); // for the 'arc' trig synonyms + if ($fnn == 'ln') $fnn = 'log'; + eval('$stack->push(' . $fnn . '($op1));'); // perfectly safe eval() + } elseif (array_key_exists($fnn, $this->f)) { // user function + // get args + $args = array(); + for ($i = count($this->f[$fnn]['args'])-1; $i >= 0; $i--) { + if (is_null($args[$this->f[$fnn]['args'][$i]] = $stack->pop())) return $this->trigger("internal error"); + } + $stack->push($this->pfx($this->f[$fnn]['func'], $args)); // yay... recursion!!!! + } + // if the token is a number or variable, push it on the stack + } else { + if (is_numeric($token)) { + $stack->push($token); + } elseif (array_key_exists($token, $this->v)) { + $stack->push($this->v[$token]); + } elseif (array_key_exists($token, $vars)) { + $stack->push($vars[$token]); + } else { + return $this->trigger("undefined variable '$token'"); + } + } + } + // when we're out of tokens, the stack should have a single element, the final result + if ($stack->count != 1) return $this->trigger("internal error"); + return $stack->pop(); + } + + // trigger an error, but nicely, if need be + function trigger($msg) { + $this->last_error = $msg; + if (!$this->suppress_errors) trigger_error($msg, E_USER_WARNING); + return false; + } +} + +// for internal use +class ctools_math_expr_stack { + + var $stack = array(); + var $count = 0; + + function push($val) { + $this->stack[$this->count] = $val; + $this->count++; + } + + function pop() { + if ($this->count > 0) { + $this->count--; + return $this->stack[$this->count]; + } + return null; + } + + function last($n=1) { + return !empty($this->stack[$this->count-$n]) ? $this->stack[$this->count-$n] : NULL; + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/menu.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..fd68847328aa7bdd33ec2789da9904de0decd8b0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/menu.inc @@ -0,0 +1,498 @@ +<?php + +/** + * @file + * General menu helper functions. + * + * The menu system was completely revamped in Drupal 6; as such it is not as + * mature as some other systems and is missing some API functions. This + * file helps smooth some edges out. + */ + +/** + * Dynamically add a tab to the current path. + * + * This function allows you to dynamically add tabs to the current path. + * There are several important considerations to this: + * + * - First, Drupal doesn't really allow this. CTools lets this happen by + * overriding the theme function that displays the tabs. That means that + * custom themes which do not use CTools functions will not get the new + * tabs. You can provide instructions to your users about how to deal with + * this, but you should be prepared for some users not getting the new tabs + * and not knowing why. + * - Second, if there is only 1 tab, Drupal will not show it. Therefore, if + * you are only adding one tab, you should find a way to make sure there is + * already tab, or instead add 2. + * - Third, the caller is responsible for providing access control to these + * links. + * + * @param $link + * An array describing this link. It must contain: + * - 'title': The printed title of the link. + * - 'href': The path of the link. This is an argument to l() so it has all + * of those features and limitations. + * - 'options': Any options that go to l, including query, fragment and html + * options necessary. + * - 'weight': The weight to use in ordering the tabs. + * - 'type': Optional. If set to MENU_DEFAULT_LOCAL_TASK this can be used to + * add a fake 'default' local task, which is useful if you have to add + * tabs to a page that has noen. + */ +function ctools_menu_add_tab($link = NULL) { + static $links = array(); + if (isset($link)) { + $links[$link['href']] = $link; + } + + return $links; +} + +/** + * CTools replacement for menu_get_menu_trail that allows us to take apart + * the menu trail if necessary. + */ +function ctools_get_menu_trail($path = NULL) { + $trail = array(); + $trail[] = array('title' => t('Home'), 'href' => '<front>', 'localized_options' => array(), 'type' => 0); + $item = menu_get_item($path); + + // Check whether the current item is a local task (displayed as a tab). + if ($item['tab_parent']) { + // The title of a local task is used for the tab, never the page title. + // Thus, replace it with the item corresponding to the root path to get + // the relevant href and title. For example, the menu item corresponding + // to 'admin' is used when on the 'By module' tab at 'admin/by-module'. + $parts = explode('/', $item['tab_root']); + $args = arg(); + // Replace wildcards in the root path using the current path. + foreach ($parts as $index => $part) { + if ($part == '%') { + $parts[$index] = $args[$index]; + } + } + // Retrieve the menu item using the root path after wildcard replacement. + $root_item = menu_get_item(implode('/', $parts)); + if ($root_item && $root_item['access']) { + $item = $root_item; + } + } + + $tree = ctools_menu_tree_page_data($item, menu_get_active_menu_name()); + list($key, $curr) = each($tree); + + while ($curr) { + // Terminate the loop when we find the current path in the active trail. + if ($curr['link']['href'] == $item['href']) { + $trail[] = $curr['link']; + $curr = FALSE; + } + else { + // Add the link if it's in the active trail, then move to the link below. + if ($curr['link']['in_active_trail']) { + $trail[] = $curr['link']; + $tree = $curr['below'] ? $curr['below'] : array(); + } + list($key, $curr) = each($tree); + } + } + // Make sure the current page is in the trail (needed for the page title), + // but exclude tabs and the front page. + $last = count($trail) - 1; + if ($trail[$last]['href'] != $item['href'] && !(bool)($item['type'] & MENU_IS_LOCAL_TASK) && !drupal_is_front_page()) { + $trail[] = $item; + } + + return $trail; +} + +/** + * Get the data structure representing a named menu tree, based on the current page. + * + * The tree order is maintained by storing each parent in an individual + * field, see http://drupal.org/node/141866 for more. + * + * @param $menu_name + * The named menu links to return + * + * @return + * An array of menu links, in the order they should be rendered. The array + * is a list of associative arrays -- these have two keys, link and below. + * link is a menu item, ready for theming as a link. Below represents the + * submenu below the link if there is one, and it is a subtree that has the + * same structure described for the top-level array. + */ +function ctools_menu_tree_page_data($item, $menu_name = 'navigation') { + static $tree = array(); + + // Generate a cache ID (cid) specific for this page. + $cid = 'links:'. $menu_name .':page-cid:'. $item['href'] .':'. (int)$item['access']; + + if (!isset($tree[$cid])) { + // If the static variable doesn't have the data, check {cache_menu}. + $cache = cache_get($cid, 'cache_menu'); + if ($cache && isset($cache->data)) { + // If the cache entry exists, it will just be the cid for the actual data. + // This avoids duplication of large amounts of data. + $cache = cache_get($cache->data, 'cache_menu'); + if ($cache && isset($cache->data)) { + $data = $cache->data; + } + } + // If the tree data was not in the cache, $data will be NULL. + if (!isset($data)) { + // Build and run the query, and build the tree. + if ($item['access']) { + // Check whether a menu link exists that corresponds to the current path. + $args = array($menu_name, $item['href']); + $placeholders = "'%s'"; + if (drupal_is_front_page()) { + $args[] = '<front>'; + $placeholders .= ", '%s'"; + } + $parents = db_fetch_array(db_query("SELECT p1, p2, p3, p4, p5, p6, p7, p8 FROM {menu_links} WHERE menu_name = '%s' AND link_path IN (". $placeholders .")", $args)); + + if (empty($parents)) { + // If no link exists, we may be on a local task that's not in the links. + // TODO: Handle the case like a local task on a specific node in the menu. + $parents = db_fetch_array(db_query("SELECT p1, p2, p3, p4, p5, p6, p7, p8 FROM {menu_links} WHERE menu_name = '%s' AND link_path = '%s'", $menu_name, $item['tab_root'])); + } + // We always want all the top-level links with plid == 0. + $parents[] = '0'; + + // Use array_values() so that the indices are numeric for array_merge(). + $args = $parents = array_unique(array_values($parents)); + $placeholders = implode(', ', array_fill(0, count($args), '%d')); + $expanded = variable_get('menu_expanded', array()); + // Check whether the current menu has any links set to be expanded. + if (in_array($menu_name, $expanded)) { + // Collect all the links set to be expanded, and then add all of + // their children to the list as well. + do { + $result = db_query("SELECT mlid FROM {menu_links} WHERE menu_name = '%s' AND expanded = 1 AND has_children = 1 AND plid IN (". $placeholders .') AND mlid NOT IN ('. $placeholders .')', array_merge(array($menu_name), $args, $args)); + $num_rows = FALSE; + while ($item = db_fetch_array($result)) { + $args[] = $item['mlid']; + $num_rows = TRUE; + } + $placeholders = implode(', ', array_fill(0, count($args), '%d')); + } while ($num_rows); + } + array_unshift($args, $menu_name); + } + else { + // Show only the top-level menu items when access is denied. + $args = array($menu_name, '0'); + $placeholders = '%d'; + $parents = array(); + } + // Select the links from the table, and recursively build the tree. We + // LEFT JOIN since there is no match in {menu_router} for an external + // link. + $data['tree'] = menu_tree_data(db_query(" + SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, m.description, ml.* + FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path + WHERE ml.menu_name = '%s' AND ml.plid IN (". $placeholders .") + ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC", $args), $parents); + $data['node_links'] = array(); + menu_tree_collect_node_links($data['tree'], $data['node_links']); + // Cache the data, if it is not already in the cache. + $tree_cid = _menu_tree_cid($menu_name, $data); + if (!cache_get($tree_cid, 'cache_menu')) { + cache_set($tree_cid, $data, 'cache_menu'); + } + // Cache the cid of the (shared) data using the page-specific cid. + cache_set($cid, $tree_cid, 'cache_menu'); + } + // Check access for the current user to each item in the tree. + menu_tree_check_access($data['tree'], $data['node_links']); + $tree[$cid] = $data['tree']; + } + return $tree[$cid]; +} + +function ctools_menu_set_trail_parent($path) { + $current = menu_get_active_trail(); + $keep = array_pop($current); + + $trail = ctools_get_menu_trail($path); + $trail[] = $keep; + + menu_set_active_trail($trail); +} + +/** + * An alternative to theme_menu_local_tasks to add flexibility to tabs. + * + * The code in theme_menu_local_tasks has no entry points to put hooks. + * Therefore, what CTools does is, if that theme function is not overridden, + * it uses hook_theme_registry_alter() to use its own version. This version + * then allows modules to use ctools_menu_add_local_task() to add a dynamic + * local task to the list. + * + * If a theme *does* override theme_menu_local_tasks, it can still get this + * functionality by using ctools versions of menu_primary_local_tasks() and + * menu_secondary_local_tasks(). + */ +function ctools_theme_menu_local_tasks() { + $output = ''; + + if ($primary = ctools_menu_primary_local_tasks()) { + $output .= "<ul class=\"tabs primary\">\n". $primary ."</ul>\n"; + } + if ($secondary = ctools_menu_secondary_local_tasks()) { + $output .= "<ul class=\"tabs secondary\">\n". $secondary ."</ul>\n"; + } + + return $output; +} + +/** + * CTools variant of menu_primary_local_tasks(). + * + * This can be called by themes which implement their own theme_menu_local_tasks + * in order to get local tasks that include CTools' additions. + */ +function ctools_menu_primary_local_tasks() { + return ctools_menu_local_tasks(0); +} + +/** + * CTools variant of menu_secondary_local_tasks(). + * + * This can be called by themes which implement their own theme_menu_local_tasks + * in order to get local tasks that include CTools' additions. + */ +function ctools_menu_secondary_local_tasks() { + return ctools_menu_local_tasks(1); +} + +/** + * CTools' variant of menu_local_tasks. + * + * This function is a new version of menu_local_tasks that is meant to be more + * flexible and allow for modules to dynamically add items to the local tasks + * using a simple function. + * + * One downside to using this is that the code to build the tabs could be run + * twice on a page if something + */ +function ctools_menu_local_tasks($level = 0, $return_root = FALSE) { + static $tabs; + static $root_path; + + if (!isset($tabs)) { + $tabs = array(); + + $router_item = menu_get_item(); + if (!$router_item || !$router_item['access']) { + return ''; + } + // Get all tabs and the root page. + $result = db_query("SELECT * FROM {menu_router} WHERE tab_root = '%s' ORDER BY weight, title", $router_item['tab_root']); + $map = arg(); + $children = array(); + $tasks = array(); + $root_path = $router_item['path']; + + while ($item = db_fetch_array($result)) { + _menu_translate($item, $map, TRUE); + if ($item['tab_parent']) { + // All tabs, but not the root page. + $children[$item['tab_parent']][$item['path']] = $item; + } + // Store the translated item for later use. + $tasks[$item['path']] = $item; + } + + // Find all tabs below the current path. + $path = $router_item['path']; + + _ctools_menu_add_dynamic_items($children[$path]); + + // Tab parenting may skip levels, so the number of parts in the path may not + // equal the depth. Thus we use the $depth counter (offset by 1000 for ksort). + $depth = 1001; + while (isset($children[$path])) { + $tabs_current = ''; + $next_path = ''; + $count = 0; + foreach ($children[$path] as $item) { + if ($item['access']) { + $count++; + // The default task is always active. + if ($item['type'] == MENU_DEFAULT_LOCAL_TASK) { + // Find the first parent which is not a default local task. + if (isset($item['tab_parent'])) { + for ($p = $item['tab_parent']; $tasks[$p]['type'] == MENU_DEFAULT_LOCAL_TASK; $p = $tasks[$p]['tab_parent']); + $href = $tasks[$p]['href']; + $next_path = $item['path']; + } + else { + $href = $item['href']; + } + $link = theme('menu_item_link', array('href' => $href) + $item); + $tabs_current .= theme('menu_local_task', $link, TRUE); + } + else { + $link = theme('menu_item_link', $item); + $tabs_current .= theme('menu_local_task', $link); + } + } + } + $path = $next_path; + $tabs[$depth]['count'] = $count; + $tabs[$depth]['output'] = $tabs_current; + $depth++; + } + + // Find all tabs at the same level or above the current one. + $parent = $router_item['tab_parent']; + $path = $router_item['path']; + $current = $router_item; + $depth = 1000; + while (isset($children[$parent])) { + $tabs_current = ''; + $next_path = ''; + $next_parent = ''; + $count = 0; + foreach ($children[$parent] as $item) { + if ($item['access']) { + $count++; + if ($item['type'] == MENU_DEFAULT_LOCAL_TASK) { + // Find the first parent which is not a default local task. + for ($p = $item['tab_parent']; $tasks[$p]['type'] == MENU_DEFAULT_LOCAL_TASK; $p = $tasks[$p]['tab_parent']); + $link = theme('menu_item_link', array('href' => $tasks[$p]['href']) + $item); + if ($item['path'] == $router_item['path']) { + $root_path = $tasks[$p]['path']; + } + } + else { + $link = theme('menu_item_link', $item); + } + // We check for the active tab. + if ($item['path'] == $path) { + $tabs_current .= theme('menu_local_task', $link, TRUE); + $next_path = $item['tab_parent']; + if (isset($tasks[$next_path])) { + $next_parent = $tasks[$next_path]['tab_parent']; + } + } + else { + $tabs_current .= theme('menu_local_task', $link); + } + } + } + $path = $next_path; + $parent = $next_parent; + $tabs[$depth]['count'] = $count; + $tabs[$depth]['output'] = $tabs_current; + $depth--; + } + // Sort by depth. + ksort($tabs); + // Remove the depth, we are interested only in their relative placement. + $tabs = array_values($tabs); + } + + if ($return_root) { + return $root_path; + } + else { + // We do not display single tabs. + return (isset($tabs[$level]) && $tabs[$level]['count'] > 1) ? $tabs[$level]['output'] : ''; + } +} + +/** + * Re-sort menu items after we have modified them. + */ +function ctools_menu_sort($a, $b) { + $a_weight = (is_array($a) && isset($a['weight'])) ? $a['weight'] : 0; + $b_weight = (is_array($b) && isset($b['weight'])) ? $b['weight'] : 0; + if ($a_weight == $b_weight) { + $a_title = (is_array($a) && isset($a['title'])) ? $a['title'] : 0; + $b_title = (is_array($b) && isset($b['title'])) ? $b['title'] : 0; + if ($a_title == $b_title) { + return 0; + } + + return ($a_title < $b_title) ? -1 : 1; + } + + return ($a_weight < $b_weight) ? -1 : 1; +} + +/** + * Theme override to use CTools to call help instead of the basic call. + * + * This is used only to try and improve performance; this calls through to + * the same functions that tabs do and executes a complex build. By overriding + * this to use the CTools version, we can prevent this query from being run + * twice on the same page. + */ +function ctools_menu_help() { + if ($help = ctools_menu_get_active_help()) { + return '<div class="help">'. $help .'</div>'; + } +} + +/** + * CTools' replacement for ctools_menu_get_active_help() + */ +function ctools_menu_get_active_help() { + $output = ''; + $router_path = ctools_menu_tab_root_path(); + // We will always have a path unless we are on a 403 or 404. + if (!$router_path) { + return ''; + } + + $arg = drupal_help_arg(arg(NULL)); + $empty_arg = drupal_help_arg(); + + foreach (module_list() as $name) { + if (module_hook($name, 'help')) { + // Lookup help for this path. + if ($help = module_invoke($name, 'help', $router_path, $arg)) { + $output .= $help ."\n"; + } + // Add "more help" link on admin pages if the module provides a + // standalone help page. + if ($arg[0] == "admin" && module_exists('help') && module_invoke($name, 'help', 'admin/help#'. $arg[2], $empty_arg) && $help) { + $output .= theme("more_help_link", url('admin/help/'. $arg[2])); + } + } + } + return $output; +} + +/** + * CTools' replacement for menu_tab_root_path() + */ +function ctools_menu_tab_root_path() { + return ctools_menu_local_tasks(0, TRUE); +} + +/** + * Returns the rendered local tasks. The default implementation renders + * them as tabs. Overridden to split the secondary tasks. + * + * @ingroup themeable + */ +function ctools_garland_menu_local_tasks() { + return ctools_menu_primary_local_tasks(); +} + +function _ctools_menu_add_dynamic_items(&$links) { + // TESTING: add hardcoded values. + if ($additions = ctools_menu_add_tab()) { + foreach ($additions as $addition) { + $links[$addition['href']] = $addition + array( + 'access' => TRUE, + 'type' => MENU_LOCAL_TASK, + ); + } + uasort($links, 'ctools_menu_sort'); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/modal.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/modal.inc new file mode 100644 index 0000000000000000000000000000000000000000..420599e2adea0af05ebf5a23aa31223fee145068 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/modal.inc @@ -0,0 +1,237 @@ +<?php + +/** + * @file + * Implement a modal form using AJAX. + * + * The modal form is implemented primarily from mc.js; this contains the + * Drupal specific stuff to use it. The modal is fairly generic and can + * be activated mostly by setting up the right classes, but if you are + * using the modal you must include links to the images in settings, + * because the javascript does not inherently know where the images are + * at. + * + * You can accomplish this with this PHP code: + * @code { + * ctools_include('modal'); + * ctools_modal_add_js(); + * } + * + * You can have links and buttons bound to use the modal by adding the + * class ctools-use-modal. + * + * For links, the href of the link will be the destination, with any + * appearance of /nojs/ converted to /ajax/. + * + * For submit buttons, however, the URL is found a different, slightly + * more complex way. The ID of the item is taken and -url is appended to + * it to derive a class name. Then, all form elements that contain that + * class name are founded and their values put together to form a + * URL. + * + * For example, let's say you have an 'add' button, and it has a select + * form item that tells your system what widget it is adding. If the id + * of the add button is edit-add, you would place a hidden input with + * the base of your URL in the form and give it a class of 'edit-add-url'. + * You would then add 'edit-add-url' as a class to the select widget + * allowing you to convert this value to the form without posting. + * + * If no URL is found, the action of the form will be used and the entire + * form posted to it. + */ + +function ctools_modal_add_js() { + // Provide a gate so we only do this once. + static $done = FALSE; + if ($done) { + return; + } + + $settings = array( + 'CToolsModal' => array( + 'loadingText' => t('Loading...'), + 'closeText' => t('Close Window'), + 'closeImage' => theme('image', ctools_image_path('icon-close-window.png'), t('Close window'), t('Close window')), + 'throbber' => theme('image', ctools_image_path('throbber.gif'), t('Loading...'), t('Loading')), + ), + ); + + drupal_add_js($settings, 'setting'); + drupal_add_js('misc/jquery.form.js'); + ctools_add_js('ajax-responder'); + ctools_add_js('modal'); + + ctools_add_css('modal'); + $done = TRUE; +} + +/** + * @todo this is deprecated + */ +function ctools_modal_add_plugin_js($plugins) { + $css = array(); + $js = array(drupal_get_path('module', 'ctools') . '/js/dependent.js' => TRUE); + foreach ($plugins as $subtype) { + if (isset($subtype['js'])) { + foreach ($subtype['js'] as $file) { + if (file_exists($file)) { + $js[$file] = TRUE; + } + else if (file(exists($subtype['path'] . '/' . $file))) { + $js[$subtype['path'] . '/' . $file] = TRUE; + } + } + } + if (isset($subtype['css'])) { + foreach ($subtype['css'] as $file) { + if (file_exists($file)) { + $css[$file] = TRUE; + } + else if (file(exists($subtype['path'] . '/' . $file))) { + $css[$subtype['path'] . '/' . $file] = TRUE; + } + } + } + } + + foreach (array_keys($js) as $file) { + drupal_add_js($file); + } + foreach (array_keys($css) as $file) { + drupal_add_css($file); + } +} + +/** + * Place HTML within the modal. + * + * @param $title + * The title of the modal. + * @param $html + * The html to place within the modal. + */ +function ctools_modal_command_display($title, $html) { + return array( + 'command' => 'modal_display', + 'title' => $title, + 'output' => $html, + ); +} + +/** + * Dismiss the modal. + */ +function ctools_modal_command_dismiss() { + return array( + 'command' => 'modal_dismiss', + ); +} + +/** + * Display loading screen in the modal + */ +function ctools_modal_command_loading() { + return array( + 'command' => 'modal_loading', + ); +} + +/** + * Render an image as a button link. This will automatically apply an AJAX class + * to the link and add the appropriate javascript to make this happen. + * + * @param $image + * The path to an image to use that will be sent to theme('image') for rendering. + * @param $dest + * The destination of the link. + * @param $alt + * The alt text of the link. + * @param $class + * Any class to apply to the link. @todo this should be a options array. + */ +function ctools_modal_image_button($image, $dest, $alt, $class = '') { + return ctools_ajax_text_button(theme('image', $image), $dest, $alt, $class, 'ctools-use-modal'); +} + +/** + * Render text as a link. This will automatically apply an AJAX class + * to the link and add the appropriate javascript to make this happen. + * + * Note: 'html' => true so be sure any text is vetted! Chances are these kinds of buttons will + * not use user input so this is a very minor concern. + * + * @param $image + * The path to an image to use that will be sent to theme('image') for rendering. + * @param $dest + * The destination of the link. + * @param $alt + * The alt text of the link. + * @param $class + * Any class to apply to the link. @todo this should be a options array. + */ +function ctools_modal_text_button($text, $dest, $alt, $class = '') { + return ctools_ajax_text_button($text, $dest, $alt, $class, 'ctools-use-modal'); +} + +/** + * Wrap a form so that we can use it properly with AJAX. Essentially if the + * form wishes to render, it automatically does that, otherwise it returns + * so we can see submission results. + * + * @return + * The output of the form, if it was rendered. If $form_state['ajax'] + * is set, this will use ctools_modal_form_render so it will be + * a $command object suitable for ctools_ajax_render already. + * + * The return will be NULL if the form was successfully submitted unless + * you specifically set re_render = TRUE. If ajax is set the + * form will never be redirected. + */ +function ctools_modal_form_wrapper($form_id, &$form_state) { + ctools_include('form'); + // This won't override settings already in. + $form_state += array( + 're_render' => FALSE, + 'no_redirect' => !empty($form_state['ajax']), + ); + + $output = ctools_build_form($form_id, $form_state); + if (!empty($form_state['ajax']) && (!$form_state['executed'] || $form_state['rebuild'])) { + return ctools_modal_form_render($form_state, $output); + } + + return $output; +} + +/** + * Render a form into an AJAX display. + */ +function ctools_modal_form_render($form_state, $output) { + $title = empty($form_state['title']) ? drupal_get_title() : $form_state['title']; + + // If there are messages for the form, render them. + if ($messages = theme('status_messages')) { + $output = $messages . $output; + } + + $commands = array(); + if (isset($form_state['js settings'])) { + $commands[] = ctools_ajax_command_settings($form_state['js settings']); + } + + $commands[] = ctools_modal_command_display($title, $output); + return $commands; +} + +/** + * Perform a simple modal render and immediately exit. + * + * This is primarily used for error displays, since usually modals will + * contain forms. + */ +function ctools_modal_render($title, $output) { + $commands = array(); + $commands[] = ctools_modal_command_display($title, $output); + ctools_include('ajax'); + ctools_ajax_render($commands); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/object-cache.cron.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/object-cache.cron.inc new file mode 100644 index 0000000000000000000000000000000000000000..99f2276ca708222a23d490747746d020a26fd98c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/object-cache.cron.inc @@ -0,0 +1,16 @@ +<?php + +/** + * @file + * Contains cron hooks for the object cache tool. + * + * We use this to clean up old object caches. + */ + +function ctools_object_cache_cron() { + if (variable_get('ctools_last_cron', 0) < time() - 86400) { + variable_set('ctools_last_cron', time()); + ctools_include('object-cache'); + ctools_object_cache_clean(); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/object-cache.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/object-cache.inc new file mode 100644 index 0000000000000000000000000000000000000000..53a49d0e9a7cddf839bb2b294745bd354b81b81f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/object-cache.inc @@ -0,0 +1,163 @@ +<?php + +/** + * @file + * The non-volatile object cache is used to store an object while it is + * being edited, so that we don't have to save until we're completely + * done. The cache should be 'cleaned' on a regular basis, meaning to + * remove old objects from the cache, but otherwise the data in this + * cache must remain stable, as it includes unsaved changes. + */ + +/** + * Get an object from the non-volatile ctools cache. + * + * This function caches in memory as well, so that multiple calls to this + * will not result in multiple database reads. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being stored. + * @param $skip_cache + * Skip the memory cache, meaning this must be read from the db again. + * + * @return + * The data that was cached. + */ +function ctools_object_cache_get($obj, $name, $skip_cache = FALSE) { + $cache = &ctools_static(__FUNCTION__, array()); + $key = "$obj:$name"; + if ($skip_cache) { + unset($cache[$key]); + } + + if (!array_key_exists($key, $cache)) { + $data = db_fetch_object(db_query("SELECT * FROM {ctools_object_cache} WHERE sid = '%s' AND obj = '%s' AND name = '%s'", session_id(), $obj, $name)); + if ($data) { + $cache[$key] = unserialize(db_decode_blob($data->data)); + } + } + return isset($cache[$key]) ? $cache[$key] : NULL; +} + +/** + * Store an object in the non-volatile ctools cache. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being stored. + * @param $cache + * The object to be cached. This will be serialized prior to writing. + */ +function ctools_object_cache_set($obj, $name, $cache) { + // Store the CTools session id in the user session to force a + // session for anonymous users in Drupal 7 and Drupal 6 Pressflow. + // see http://drupal.org/node/562374, http://drupal.org/node/861778 + if (empty($GLOBALS['user']->uid) && empty($_SESSION['ctools_session_id'])) { + $_SESSION['ctools_hold_session'] = TRUE; + } + + ctools_object_cache_clear($obj, $name); + db_query("INSERT INTO {ctools_object_cache} (sid, obj, name, data, updated) VALUES ('%s', '%s', '%s', %b, %d)", session_id(), $obj, $name, serialize($cache), time()); +} + +/** + * Remove an object from the non-volatile ctools cache + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being removed. + */ +function ctools_object_cache_clear($obj, $name) { + db_query("DELETE FROM {ctools_object_cache} WHERE sid = '%s' AND obj = '%s' AND name = '%s'", session_id(), $obj, $name); + // Ensure the static cache is emptied of this obj:name set. + $cache = &ctools_static('ctools_object_cache_get', array()); + unset($cache["$obj:$name"]); +} + + +/** + * Determine if another user has a given object cached. + * + * This is very useful for 'locking' objects so that only one user can + * modify them. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being removed. + * + * @return + * An object containing the UID and updated date if found; NULL if not. + */ +function ctools_object_cache_test($obj, $name) { + return db_fetch_object(db_query("SELECT s.uid, c.updated FROM {ctools_object_cache} c INNER JOIN {sessions} s ON c.sid = s.sid WHERE s.sid != '%s' AND c.obj = '%s' AND c.name = '%s' ORDER BY c.updated ASC", session_id(), $obj, $name)); +} + +/** + * Get the cache status of a group of objects. + * + * This is useful for displaying lock status when listing a number of objects + * an an administration UI. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $names + * An array of names of objects + * + * @return + * An array of objects containing the UID and updated date for each name found. + */ +function ctools_object_cache_test_objects($obj, $names) { + $placeholders = db_placeholders($names, 'varchar'); + $args = array_merge(array($obj), $names); + $result = db_query("SELECT c.name, s.uid, c.updated FROM {ctools_object_cache} c INNER JOIN {sessions} s ON c.sid = s.sid WHERE c.obj = '%s' AND c.name IN ($placeholders) ORDER BY c.updated ASC", $args); + + $return = array(); + while ($test = db_fetch_object($result)) { + $return[$test->name] = $test; + } + + return $return; +} + +/** + * Remove an object from the non-volatile ctools cache for all session IDs. + * + * This is useful for clearing a lock. + * + * @param $obj + * A 32 character or less string to define what kind of object is being + * stored; primarily this is used to prevent collisions. + * @param $name + * The name of the object being removed. + */ +function ctools_object_cache_clear_all($obj, $name) { + db_query("DELETE FROM {ctools_object_cache} WHERE obj = '%s' AND name = '%s'", $obj, $name); + // Ensure the static cache is emptied of this obj:name set. + $cache = &ctools_static('ctools_object_cache_get', array()); + unset($cache["$obj:$name"]); +} + +/** + * Remove all objects in the object cache that are older than the + * specified age. + * + * @param $age + * The minimum age of objects to remove, in seconds. For example, 86400 is + * one day. Defaults to 7 days. + */ +function ctools_object_cache_clean($age = NULL) { + if (empty($age)) { + $age = 86400 * 7; // 7 days + } + db_query("DELETE FROM {ctools_object_cache} WHERE updated < %d", time() - $age); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/page-wizard.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/page-wizard.inc new file mode 100644 index 0000000000000000000000000000000000000000..bbdfbd82ae00058eda7e640b4fb71e0c35b68ca7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/page-wizard.inc @@ -0,0 +1,190 @@ +<?php + +/** + * Fetch metadata on a specific page_wizard plugin. + * + * @param $page_wizard + * Name of a panel page_wizard. + * + * @return + * An array with information about the requested panel page_wizard. + */ +function page_manager_get_page_wizard($page_wizard) { + ctools_include('plugins'); + return ctools_get_plugins('page_manager', 'page_wizards', $page_wizard); +} + +/** + * Fetch metadata for all page_wizard plugins. + * + * @return + * An array of arrays with information about all available panel page_wizards. + */ +function page_manager_get_page_wizards() { + ctools_include('plugins'); + return ctools_get_plugins('page_manager', 'page_wizards'); +} + +/** + * Get the cached changes to a given wizard. + * + * @return + * A $cache object or a clean cache object if none could be loaded. + */ +function page_manager_get_wizard_cache($plugin) { + if (is_string($plugin)) { + $plugin = page_manager_get_page_wizard($plugin); + } + + if (empty($plugin)) { + return; + } + + ctools_include('object-cache'); + + // Since contexts might be cache, include this so they load. + ctools_include('context'); + $cache = ctools_object_cache_get('page_manager_page_wizard', $plugin['name']); + if (!$cache) { + $cache = page_manager_make_wizard_cache($plugin); + } + + return $cache; +} + +function page_manager_make_wizard_cache($plugin) { + $cache = new stdClass; + $cache->plugin = $plugin; + if ($function = ctools_plugin_get_function($plugin, 'default cache')) { + $function($cache); + } + + return $cache; +} + +/** + * Store changes to a task handler in the object cache. + */ +function page_manager_set_wizard_cache($cache) { + ctools_include('object-cache'); + ctools_object_cache_set('page_manager_page_wizard', $cache->plugin['name'], $cache); +} + +/** + * Remove an item from the object cache. + */ +function page_manager_clear_wizard_cache($name) { + ctools_include('object-cache'); + ctools_object_cache_clear('page_manager_page_wizard', $name); +} + +/** + * Menu callback for the page wizard. + */ +function page_manager_page_wizard($name, $step = NULL) { + $plugin = page_manager_get_page_wizard($name); + if (!$plugin) { + return MENU_NOT_FOUND; + } + + // Check for simple access string on plugin. + if (!empty($plugin['access']) && !user_access($plugin['access'])) { + return MENU_ACCESS_DENIED; + } + + // Check for possibly more complex access callback on plugin. + if ($function = ctools_plugin_get_function($plugin, 'access callback') && !$function($plugin)) { + return MENU_ACCESS_DENIED; + } + + // Create a basic wizard.in form info array and merge it with the + // plugin's. + $form_info = array( + 'id' => 'page_manager_page_wizard', + 'show trail' => TRUE, + 'show back' => TRUE, + 'show return' => FALSE, + 'show cancel' => FALSE, + 'next callback' => 'page_manager_page_wizard_next', + 'finish callback' => 'page_manager_page_wizard_finish', + + 'path' => "admin/build/pages/wizard/$name/%step", + ); + + $form_info = array_merge_recursive($form_info, $plugin['form info']); + + // If step is unset, go with the basic step. + if (!isset($step)) { + $step = current(array_keys($form_info['order'])); + $cache = page_manager_make_wizard_cache($plugin); + } + else { + $cache = page_manager_get_wizard_cache($plugin); + } + + ctools_include('wizard'); + $form_state = array( + 'plugin' => $plugin, + 'cache' => $cache, + 'type' => 'edit', + 'rerender' => TRUE, + 'step' => $step, + ); + + if (isset($plugin['page title'])) { + drupal_set_title($plugin['page title']); + } + + if ($function = ctools_plugin_get_function($form_state['plugin'], 'start')) { + $function($form_info, $step, $form_state); + } + + $output = ctools_wizard_multistep_form($form_info, $step, $form_state); + return $output; +} + +/** + * Callback generated when the add page process is finished. + */ +function page_manager_page_wizard_finish(&$form_state) { + if ($function = ctools_plugin_get_function($form_state['plugin'], 'finish')) { + $function($form_state); + } + + page_manager_clear_wizard_cache($form_state['cache']->plugin['name']); +} + +/** + * Callback generated when the 'next' button is clicked. + * + * All we do here is store the cache. + */ +function page_manager_page_wizard_next(&$form_state) { + if ($function = ctools_plugin_get_function($form_state['plugin'], 'next')) { + $function($form_state); + } + + page_manager_set_wizard_cache($form_state['cache']); +} + +/** + * Provide a simple administrative list of all wizards. + * + * This is called as a page callback, but can also be used by any module + * that wants to get a list of wizards for its type. + */ +function page_manager_page_wizard_list($type = NULL) { + $plugins = page_manager_get_page_wizards(); + uasort($plugins, 'ctools_plugin_sort'); + + $output = '<dl class="page-manager-wizards">'; + foreach ($plugins as $id => $plugin) { + if (!$type || (isset($plugin['type']) && $plugin['type'] == $type)) { + $output .= '<dt>' . l($plugin['title'], 'admin/build/pages/wizard/' . $id) . '</dt>'; + $output .= '<dd class="description">' . $plugin['description'] . '</dd>'; + } + } + $output .= '</dl>'; + + return $output; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/page-wizard.menu.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/page-wizard.menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..94e6db653feaedf3d57787d5d69bea38e02a04ed --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/page-wizard.menu.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Contains menu item registration for the page manager page wizards tool. + */ + +function ctools_page_wizard_menu(&$items) { + if (!module_exists('page_manager')) { + return; + } + + $base = array( + 'access arguments' => array('use page manager'), + 'file' => 'includes/page-wizard.inc', + 'type' => MENU_CALLBACK, + ); + + $items['admin/build/pages/wizard'] = array( + 'title' => 'Wizards', + 'page callback' => 'page_manager_page_wizard_list', + 'page arguments' => array(4), + 'weight' => -5, + 'type' => MENU_LOCAL_TASK, + ) + $base; + + $items['admin/build/pages/wizard/%'] = array( + 'title' => 'Wizard', + 'page callback' => 'page_manager_page_wizard', + 'page arguments' => array(4), + ) + $base; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/plugins.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/plugins.inc new file mode 100644 index 0000000000000000000000000000000000000000..b57767ef7f4013dd574c7d9bf674bb5a137eb2b0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/plugins.inc @@ -0,0 +1,837 @@ +<?php + +/** + * @file + * + * Contains routines to organize and load plugins. It allows a special + * variation of the hook system so that plugins can be kept in separate + * .inc files, and can be either loaded all at once or loaded only when + * necessary. + */ + +/** + * Get an array of information about modules that support an API. + * + * This will ask each module if they support the given API, and if they do + * it will return an array of information about the modules that do. + * + * This function invokes hook_ctools_api. This invocation is statically + * cached, so feel free to call it as often per page run as you like, it + * will cost very little. + * + * This function can be used as an alternative to module_implements and can + * thus be used to find a precise list of modules that not only support + * a given hook (aka 'api') but also restrict to only modules that use + * the given version. This will allow multiple modules moving at different + * paces to still be able to work together and, in the event of a mismatch, + * either fall back to older behaviors or simply cease loading, which is + * still better than a crash. + * + * @param $owner + * The name of the module that controls the API. + * @param $api + * The name of the api. The api name forms the file name: + * $module.$api.inc + * @param $minimum_version + * The lowest version API that is compatible with this one. If a module + * reports its API as older than this, its files will not be loaded. This + * should never change during operation. + * @param $current_version + * The current version of the api. If a module reports its minimum API as + * higher than this, its files will not be loaded. This should never change + * during operation. + * + * @return + * An array of API information, keyed by module. Each module's information will + * contain: + * - 'version': The version of the API required by the module. The module + * should use the lowest number it can support so that the widest range + * of supported versions can be used. + * - 'path': If not provided, this will be the module's path. This is + * where the module will store any subsidiary files. This differs from + * plugin paths which are figured separately. + * + * APIs can request any other information to be placed here that they might + * need. This should be in the documentation for that particular API. + */ +function ctools_plugin_api_info($owner, $api, $minimum_version, $current_version) { + $cache = &ctools_static(__FUNCTION__, array()); + if (!isset($cache[$owner][$api])) { + $cache[$owner][$api] = array(); + foreach (module_implements('ctools_plugin_api') as $module) { + $function = $module . '_ctools_plugin_api'; + $info = $function($owner, $api); + if (!isset($info['version'])) { + continue; + } + + // Only process if version is between minimum and current, inclusive. + if ($info['version'] >= $minimum_version && $info['version'] <= $current_version) { + if (!isset($info['path'])) { + $info['path'] = drupal_get_path('module', $module); + } + $cache[$owner][$api][$module] = $info; + } + } + + // And allow themes to implement these as well. + $themes = _ctools_list_themes(); + foreach ($themes as $name => $theme) { + if (!empty($theme->info['api'][$owner][$api])) { + $info = $theme->info['api'][$owner][$api]; + if (!isset($info['version'])) { + continue; + } + + // Only process if version is between minimum and current, inclusive. + if ($info['version'] >= $minimum_version && $info['version'] <= $current_version) { + if (!isset($info['path'])) { + $info['path'] = ''; + } + // Because themes can't easily specify full path, we add it here + // even though we do not for modules: + $info['path'] = drupal_get_path('theme', $name) . '/' . $info['path']; + $cache[$owner][$api][$name] = $info; + } + } + } + } + + return $cache[$owner][$api]; +} + +/** + * Load a group of API files. + * + * This will ask each module if they support the given API, and if they do + * it will load the specified file name. The API and the file name + * coincide by design. + * + * @param $owner + * The name of the module that controls the API. + * @param $api + * The name of the api. The api name forms the file name: + * $module.$api.inc, though this can be overridden by the module's response. + * @param $minimum_version + * The lowest version API that is compatible with this one. If a module + * reports its API as older than this, its files will not be loaded. This + * should never change during operation. + * @param $current_version + * The current version of the api. If a module reports its minimum API as + * higher than this, its files will not be loaded. This should never change + * during operation. + * + * @return + * The API information, in case you need it. + */ +function ctools_plugin_api_include($owner, $api, $minimum_version, $current_version) { + static $already_done = array(); + + $info = ctools_plugin_api_info($owner, $api, $minimum_version, $current_version); + if (!isset($already_done[$owner][$api])) { + foreach ($info as $module => $plugin_info) { + if (!isset($plugin_info['file'])) { + $plugin_info['file'] = "$module.$api.inc"; + } + if (file_exists("./$plugin_info[path]/$plugin_info[file]")) { + $plugin_info[$module]['included'] = TRUE; + require_once "./$plugin_info[path]/$plugin_info[file]"; + } + $info[$module] = $plugin_info; + } + $already_done[$owner][$api] = TRUE; + } + + return $info; +} + +/** + * Fetch a group of plugins by name. + * + * @param $module + * The name of the module that utilizes this plugin system. It will be + * used to call hook_ctools_plugin_$plugin() to get more data about the plugin. + * @param $type + * The type identifier of the plugin. + * @param $id + * If specified, return only information about plugin with this identifier. + * The system will do its utmost to load only plugins with this id. + * + * @return + * An array of information arrays about the plugins received. The contents + * of the array are specific to the plugin. + */ +function ctools_get_plugins($module, $type, $id = NULL) { + // Store local caches of plugins and plugin info so we don't have to do full + // lookups everytime. + $info = &ctools_static('ctools_plugin_info', array()); + $plugins = &ctools_static('ctools_plugins', array()); + + // Attempt to shortcut this whole piece of code if we already have + // the requested plugin: + if ($id && isset($plugins[$module][$type]) && array_key_exists($id, $plugins[$module][$type])) { + return $plugins[$module][$type][$id]; + } + + // Store the status of plugin loading. If a module plugin type pair is true, + // then it is fully loaded and no searching or setup needs to be done. + $setup = &ctools_static('ctools_plugin_setup', array()); + + // Request metadata/defaults for this plugin from the declaring module. This + // is done once per page request, upon a request being made for that plugin. + if (!isset($info[$module][$type])) { + $info[$module][$type] = ctools_plugin_get_info($module, $type); + // Also, initialize the local plugin cache. + $plugins[$module][$type] = array(); + } + + // We assume we don't need to build a cache. + $build_cache = FALSE; + + // If the plugin info says this can be cached, check cache first. + if ($info[$module][$type]['cache'] && empty($setup[$module][$type])) { + $cache = cache_get("plugins:$module:$type", $info[$module][$type]['cache table']); + + if (!empty($cache->data)) { + // Cache load succeeded so use the cached plugin list. + $plugins[$module][$type] = $cache->data; + // Set $setup to true so we know things where loaded. + $setup[$module][$type] = TRUE; + } + else { + // Cache load failed so store that we need to build and write the cache. + $build_cache = TRUE; + } + } + + // Always load all hooks if we need them. Note we only need them now if the + // plugin asks for them. We can assume that if we have plugins we've already + // called the global hook. + if (!empty($info[$module][$type]['use hooks']) && empty($plugins[$module][$type])) { + $plugins[$module][$type] = ctools_plugin_load_hooks($info[$module][$type]); + } + + // Then see if we should load all files. We only do this if we + // want a list of all plugins or there was a cache miss. + if (empty($setup[$module][$type]) && ($build_cache || !$id)) { + $setup[$module][$type] = TRUE; + $plugins[$module][$type] = array_merge($plugins[$module][$type], ctools_plugin_load_includes($info[$module][$type])); + // If the plugin can have child plugins, and we're loading all plugins, + // go through the list of plugins we have and find child plugins. + if (!$id && !empty($info[$module][$type]['child plugins'])) { + // If a plugin supports children, go through each plugin and ask. + $temp = array(); + foreach ($plugins[$module][$type] as $name => $plugin) { + if (!empty($plugin['get children']) && function_exists($plugin['get children'])) { + $temp = array_merge($plugin['get children']($plugin, $name), $temp); + } + else { + $temp[$name] = $plugin; + } + } + $plugins[$module][$type] = $temp; + } + } + + + // If we were told earlier that this is cacheable and the cache was + // empty, give something back. + if ($build_cache) { + cache_set("plugins:$module:$type", $plugins[$module][$type], $info[$module][$type]['cache table']); + } + + // If no id was requested, we are finished here: + if (!$id) { + // Use array_filter because looking for unknown plugins could cause NULL + // entries to appear in the list later. + return array_filter($plugins[$module][$type]); + } + + // Check to see if we need to look for the file + if (!array_key_exists($id, $plugins[$module][$type])) { + // If we can have child plugins, check to see if the plugin name is in the + // format of parent:child and break it up if it is. + if (!empty($info[$module][$type]['child plugins']) && strpos($id, ':') !== FALSE) { + list($parent, $child) = explode(':', $id, 2); + } + else { + $parent = $id; + } + + if (!array_key_exists($parent, $plugins[$module][$type])) { + $result = ctools_plugin_load_includes($info[$module][$type], $parent); + // Set to either what was returned or NULL. + $plugins[$module][$type][$parent] = isset($result[$parent]) ? $result[$parent] : NULL; + } + + // If we are looking for a child, and have the parent, ask the parent for the child. + if (!empty($child) && !empty($plugins[$module][$type][$parent]) && function_exists($plugins[$module][$type][$parent]['get child'])) { + $plugins[$module][$type][$id] = $plugins[$module][$type][$parent]['get child']($plugins[$module][$type][$parent], $parent, $child); + } + } + + // At this point we should either have the plugin, or a NULL. + return $plugins[$module][$type][$id]; +} + +/** + * Reset all static caches that affect the result of ctools_get_plugins(). + */ +function ctools_get_plugins_reset() { + ctools_static_reset('ctools_plugin_load_includes'); + ctools_static_reset('ctools_plugin_api_info'); +} + +/** + * Load plugins from a directory. + * + * @param $info + * The plugin info as returned by ctools_plugin_get_info() + * @param $file + * The file to load if we're looking for just one particular plugin. + * + * @return + * An array of information created for this plugin. + */ +function ctools_plugin_load_includes($info, $filename = NULL) { + // Keep a static array so we don't hit drupal_system_listing more than necessary. + $all_files = &ctools_static(__FUNCTION__, array()); + + // store static of plugin arrays for reference because they can't be reincluded. + static $plugin_arrays = array(); + + // If we're being asked for all plugins of a type, skip any caching + // we may have done because this is an admin task and it's ok to + // spend the extra time. + if (!isset($filename)) { + $all_files[$info['module']][$info['type']] = NULL; + } + + if (!isset($all_files[$info['module']][$info['type']])) { + // If a filename was set, we will try to load our list of files from + // cache. This is considered normal operation and we try to reduce + // the time spent finding files. + if (isset($filename)) { + $cache = cache_get("ctools_plugin_files:$info[module]:$info[type]"); + if ($cache) { + $all_files[$info['module']][$info['type']] = $cache->data; + } + } + + if (!isset($all_files[$info['module']][$info['type']])) { + $all_files[$info['module']][$info['type']] = array(); + // Load all our plugins. + $directories = ctools_plugin_get_directories($info); + $extension = empty($info['info file']) ? $info['extension'] : 'info'; + + foreach ($directories as $module => $path) { + $all_files[$info['module']][$info['type']][$module] = drupal_system_listing('\.' . $extension . '$', $path, 'name', 0); + } + + cache_set("ctools_plugin_files:$info[module]:$info[type]", $all_files[$info['module']][$info['type']]); + } + } + $file_list = $all_files[$info['module']][$info['type']]; + $plugins = array(); + + // Iterate through all the plugin .inc files, load them and process the hook + // that should now be available. + foreach (array_filter($file_list) as $module => $files) { + if ($filename) { + $files = isset($files[$filename]) ? array($filename => $files[$filename]) : array(); + } + foreach ($files as $file) { + if (!empty($info['info file'])) { + // Parse a .info file + $result = ctools_plugin_process_info($info, $module, $file); + } + else { + // Parse a hook. + $plugin = NULL; // ensure that we don't have something leftover from earlier. + + if (isset($plugin_arrays[$file->filename])) { + $identifier = $plugin_arrays[$file->filename]; + } + else { + + require_once './' . $file->filename; + // .inc files have a special format for the hook identifier. + // For example, 'foo.inc' in the module 'mogul' using the plugin + // whose hook is named 'borg_type' should have a function named (deep breath) + // mogul_foo_borg_type() + + // If, however, the .inc file set the quasi-global $plugin array, we + // can use that and not even call a function. Set the $identifier + // appropriately and ctools_plugin_process() will handle it. + if (isset($plugin)) { + $plugin_arrays[$file->filename] = $plugin; + $identifier = $plugin; + } + else { + $identifier = $module . '_' . $file->name; + } + } + $result = ctools_plugin_process($info, $module, $identifier, dirname($file->filename), basename($file->filename), $file->name); + } + if (is_array($result)) { + $plugins = array_merge($plugins, $result); + } + } + } + return $plugins; +} + +/** + * Get a list of directories to search for plugins of the given type. + * + * This utilizes hook_ctools_plugin_directory() to determine a complete list of + * directories. Only modules that implement this hook and return a string + * value will have their directories included. + * + * @param $info + * The $info array for the plugin as returned by ctools_plugin_get_info(). + * + * @return array $directories + * An array of directories to search. + */ +function ctools_plugin_get_directories($info) { + $directories = array(); + + foreach (module_implements('ctools_plugin_directory') as $module) { + $function = $module . '_ctools_plugin_directory'; + $result = $function($info['module'], $info['type']); + if ($result && is_string($result)) { + $directories[$module] = drupal_get_path('module', $module) . '/' . $result; + } + } + + if (!empty($info['load themes'])) { + $themes = _ctools_list_themes(); + foreach ($themes as $name => $theme) { + if (!empty($theme->info['plugins'][$info['module']][$info['type']])) { + $directories[$name] = drupal_get_path('theme', $name) . '/' . $theme->info['plugins'][$info['module']][$info['type']]; + } + } + } + return $directories; +} + +/** + * Helper function to build a ctools-friendly list of themes capable of + * providing plugins. + * + * @return array $themes + * A list of themes that can act as plugin providers, sorted parent-first with + * the active theme placed last. + */ +function _ctools_list_themes() { + static $themes; + if (is_null($themes)) { + $current = variable_get('theme_default', FALSE); + $themes = $active = array(); + $all_themes = list_themes(); + foreach ($all_themes as $name => $theme) { + // Only search from active themes + if (empty($theme->status) && $theme->name != $current) { + continue; + } + $active[$name] = $theme; + // Prior to drupal 6.14, $theme->base_themes does not exist. Build it. + if (!isset($theme->base_themes) && !empty($theme->base_theme)) { + $active[$name]->base_themes = ctools_find_base_themes($all_themes, $name); + } + } + + // Construct a parent-first list of all themes + foreach ($active as $name => $theme) { + $base_themes = isset($theme->base_themes) ? $theme->base_themes : array(); + $themes = array_merge($themes, $base_themes, array($name => $theme->info['name'])); + } + // Put the actual theme info objects into the array + foreach (array_keys($themes) as $name) { + $themes[$name] = $all_themes[$name]; + } + + // Make sure the current default theme always gets the last word + if ($current_key = array_search($current, array_keys($themes))) { + $themes += array_splice($themes, $current_key, 1); + } + } + return $themes; +} + + +/** + * Find all the base themes for the specified theme. + * + * Themes can inherit templates and function implementations from earlier themes. + * + * NOTE: this is a verbatim copy of system_find_base_themes(), which was not + * implemented until 6.14. It is included here only as a fallback for outdated + * versions of drupal core. + * + * @param $themes + * An array of available themes. + * @param $key + * The name of the theme whose base we are looking for. + * @param $used_keys + * A recursion parameter preventing endless loops. + * @return + * Returns an array of all of the theme's ancestors; the first element's value + * will be NULL if an error occurred. + */ +function ctools_find_base_themes($themes, $key, $used_keys = array()) { + $base_key = $themes[$key]->info['base theme']; + // Does the base theme exist? + if (!isset($themes[$base_key])) { + return array($base_key => NULL); + } + + $current_base_theme = array($base_key => $themes[$base_key]->info['name']); + + // Is the base theme itself a child of another theme? + if (isset($themes[$base_key]->info['base theme'])) { + // Do we already know the base themes of this theme? + if (isset($themes[$base_key]->base_themes)) { + return $themes[$base_key]->base_themes + $current_base_theme; + } + // Prevent loops. + if (!empty($used_keys[$base_key])) { + return array($base_key => NULL); + } + $used_keys[$base_key] = TRUE; + return ctools_find_base_themes($themes, $base_key, $used_keys) + $current_base_theme; + } + // If we get here, then this is our parent theme. + return $current_base_theme; +} + + +/** + * Load plugin info for the provided hook; this is handled separately from + * plugins from files. + * + * @param $info + * The info array about the plugin as created by ctools_plugin_get_info() + * + * @return + * An array of info supplied by any hook implementations. + */ +function ctools_plugin_load_hooks($info) { + $hooks = array(); + foreach (module_implements($info['hook']) as $module) { + $result = ctools_plugin_process($info, $module, $module, drupal_get_path('module', $module)); + if (is_array($result)) { + $hooks = array_merge($hooks, $result); + } + } + return $hooks; +} + +/** + * Process a single hook implementation of a ctools plugin. + * + * @param $info + * The $info array about the plugin as returned by ctools_plugin_get_info() + * @param $module + * The module that implements the plugin being processed. + * @param $identifier + * The plugin identifier, which is used to create the name of the hook + * function being called. + * @param $path + * The path where files utilized by this plugin will be found. + * @param $file + * The file that was loaded for this plugin, if it exists. + * @param $base + * The base plugin name to use. If a file was loaded for the plugin, this + * is the plugin to assume must be present. This is used to automatically + * translate the array to make the syntax more friendly to plugin + * implementors. + */ +function ctools_plugin_process($info, $module, $identifier, $path, $file = NULL, $base = NULL) { + if (is_array($identifier)) { + $result = $identifier; + } + else { + $function = $identifier . '_' . $info['hook']; + if (!function_exists($function)) { + return NULL; + } + $result = $function(); + if (!isset($result) || !is_array($result)) { + return NULL; + } + } + + // Automatically convert to the proper format that lets plugin implementations + // not nest arrays as deeply as they used to, but still support the older + // format where they do: + if ($base && (!isset($result[$base]) || !is_array($result[$base]))) { + $result = array($base => $result); + } + + return _ctools_process_data($result, $info, $module, $path, $file); +} + +/** + * Fill in default values and run hooks for data loaded for one or + * more plugins. + */ +function _ctools_process_data($result, $info, $module, $path, $file) { + // Fill in global defaults. + foreach ($result as $name => $plugin) { + $result[$name] += array( + 'module' => $module, + 'name' => $name, + 'path' => $path, + 'file' => $file, + 'plugin module' => $info['module'], + 'plugin type' => $info['type'], + ); + + // Fill in plugin-specific defaults, if they exist. + if (!empty($info['defaults'])) { + if (is_array($info['defaults'])) { + $result[$name] += $info['defaults']; + } + // FIXME This callback-based approach for the 'defaults' key is entirely + // redundant with the 'process' callback. Consequently, that approach is + // DEPRECATED in favor using a 'process' callback. In the next major + // version, 'defaults' callbacks will be removed entirely; only the array + // addition 'defaults' approach will be allowed. + else if (function_exists($info['defaults'])) { + $info['defaults']($info, $result[$name]); + } + } + + // Allow the plugin owner to do additional processing. + if (!empty($info['process']) && function_exists($info['process'])) { + $info['process']($result[$name], $info); + } + } + return $result; +} + + +/** + * Process an info file for plugin information, rather than a hook. + */ +function ctools_plugin_process_info($info, $module, $file) { + $result = drupal_parse_info_file($file->filename); + if ($result) { + $result = array($file->name => $result); + return _ctools_process_data($result, $info, $module, dirname($file->filename), basename($file->filename)); + } +} + +/** + * Ask a module for info about a particular plugin type. + */ +function ctools_plugin_get_info($module, $type) { + $info = array(); + $function = $module . '_ctools_plugin_' . $type; + if (function_exists($function)) { + $info = $function(); + } + + // Apply defaults. Array addition will not overwrite pre-existing keys. + $info += array( + 'module' => $module, + 'type' => $type, + 'cache' => FALSE, + 'cache table' => 'cache', + 'use hooks' => TRUE, // TODO will default to FALSE in next major version + 'defaults' => array(), + 'process' => '', + 'extension' => 'inc', + 'info file' => FALSE, + 'hook' => $module . '_' . $type, + 'load themes' => FALSE, + ); + + return $info; +} + +/** + * Get a function from a plugin, if it exists. If the plugin is not already + * loaded, try ctools_plugin_load_function() instead. + * + * @param $plugin_definition + * The loaded plugin type. + * @param $function_name + * The identifier of the function. For example, 'settings form'. + * + * @return + * The actual name of the function to call, or NULL if the function + * does not exist. + */ +function ctools_plugin_get_function($plugin_definition, $function_name) { + // If cached the .inc file may not have been loaded. require_once is quite safe + // and fast so it's okay to keep calling it. + if (isset($plugin_definition['file'])) { + // Plugins that are loaded from info files have the info file as + // $plugin['file']. Don't try to run those. + $info = ctools_plugin_get_info($plugin_definition['plugin module'], $plugin_definition['plugin type']); + if (empty($info['info file'])) { + require_once './' . $plugin_definition['path'] . '/' . $plugin_definition['file']; + } + } + + if (!isset($plugin_definition[$function_name])) { + return; + } + + if (is_array($plugin_definition[$function_name]) && isset($plugin_definition[$function_name]['function'])) { + $function = $plugin_definition[$function_name]['function']; + if (isset($plugin_definition[$function_name]['file'])) { + $file = $plugin_definition[$function_name]['file']; + if (isset($plugin_definition[$function_name]['path'])) { + $file = $plugin_definition[$function_name]['path'] . '/' . $file; + } + require_once './' . $file; + } + } + else { + $function = $plugin_definition[$function_name]; + } + + if (function_exists($function)) { + return $function; + } +} + +/** + * Load a plugin and get a function name from it, returning success only + * if the function exists. + * + * @param $module + * The module that owns the plugin type. + * @param $type + * The type of plugin. + * @param $id + * The id of the specific plugin to load. + * @param $function_name + * The identifier of the function. For example, 'settings form'. + * + * @return + * The actual name of the function to call, or NULL if the function + * does not exist. + */ +function ctools_plugin_load_function($module, $type, $id, $function_name) { + $plugin = ctools_get_plugins($module, $type, $id); + return ctools_plugin_get_function($plugin, $function_name); +} + +/** + * Get a class from a plugin, if it exists. If the plugin is not already + * loaded, try ctools_plugin_load_class() instead. + * + * @param $plugin_definition + * The loaded plugin type. + * @param $class_name + * The identifier of the class. For example, 'handler'. + * @param $abstract + * If true, will return abstract classes. Otherwise, parents will be included but nothing will be returned. + * + * @return + * The actual name of the class to call, or NULL if the class does not exist. + */ +function ctools_plugin_get_class($plugin_definition, $class_name, $abstract = FALSE) { + // If cached the .inc file may not have been loaded. require_once is quite safe + // and fast so it's okay to keep calling it. + if (isset($plugin_definition['file'])) { + // Plugins that are loaded from info files have the info file as + // $plugin['file']. Don't try to run those. + $info = ctools_plugin_get_info($plugin_definition['plugin module'], $plugin_definition['plugin type']); + if (empty($info['info file'])) { + require_once './' . $plugin_definition['path'] . '/' . $plugin_definition['file']; + } + } + + if (!isset($plugin_definition[$class_name])) { + return; + } + + if (is_array($plugin_definition[$class_name]) && isset($plugin_definition[$class_name]['class'])) { + if (isset($plugin_definition[$class_name]['parent'])) { + // Make sure parents are included. + // TODO parent-loading needs to be better documented; the 'parent' designated + // on the plugin actually corresponds not to the name of the parent CLASS, + // but the name of the parent PLUGIN (and it then loads loads whatever + // class is in the same $class_name slot). Initially unintuitive. + ctools_plugin_load_class($plugin_definition['plugin module'], $plugin_definition['plugin type'], $plugin_definition[$class_name]['parent'], $class_name); + } + $class = $plugin_definition[$class_name]['class']; + if (isset($plugin_definition[$class_name]['file'])) { + $file = $plugin_definition[$class_name]['file']; + if (isset($plugin_definition[$class_name]['path'])) { + $file = $plugin_definition[$class_name]['path'] . '/' . $file; + } + require_once './' . $file; + } + } + else { + $class = $plugin_definition[$class_name]; + } + + // If we didn't explicitly include a file above, try autoloading a file + // based on the class' name. + if (!isset($file) && file_exists($plugin_definition['path'] . "/$class.class.php")) { + require_once $plugin_definition['path'] . "/$class.class.php"; + } + + if (class_exists($class) && + (empty($plugin_definition[$class_name]['abstract']) || $abstract)) { + return $class; + } +} + +/** + * Load a plugin and get a class name from it, returning success only if the + * class exists. + * + * @param $module + * The module that owns the plugin type. + * @param $type + * The type of plugin. + * @param $id + * The id of the specific plugin to load. + * @param $class_name + * The identifier of the class. For example, 'handler'. + * @param $abstract + * If true, will tell ctools_plugin_get_class to allow the return of abstract classes. + * + * @return + * The actual name of the class to call, or NULL if the class does not exist. + */ +function ctools_plugin_load_class($module, $type, $id, $class_name, $abstract = FALSE) { + $plugin = ctools_get_plugins($module, $type, $id); + return ctools_plugin_get_class($plugin, $class_name, $abstract); +} + +/** + * Sort callback for sorting plugins naturally. + * + * Sort first by weight, then by title. + */ +function ctools_plugin_sort($a, $b) { + if (is_object($a)) { + $a = (array) $a; + } + if (is_object($b)) { + $b = (array) $b; + } + + if (empty($a['weight'])) { + $a['weight'] = 0; + } + + if (empty($b['weight'])) { + $b['weight'] = 0; + } + + if ($a['weight'] == $b['weight']) { + return strnatcmp(strtolower($a['title']), strtolower($b['title'])); + } + return ($a['weight'] < $b['weight']) ? -1 : 1; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/stylizer.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/stylizer.inc new file mode 100644 index 0000000000000000000000000000000000000000..b5083fc7b5387eb50eec9bbe3717fde397b89df5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/stylizer.inc @@ -0,0 +1,1739 @@ +<?php +/** + * @file + * Create customized CSS and images from palettes created by user input. + */ + +/** + * Fetch metadata on a specific style_base plugin. + * + * @param $content type + * Name of a panel content type. + * + * @return + * An array with information about the requested stylizer style base. + */ +function ctools_get_style_base($style_base) { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'style_bases', $style_base); +} + +/** + * Fetch metadata for all style_base plugins. + * + * @return + * An array of arrays with information about all available styleizer style bases. + */ +function ctools_get_style_bases() { + ctools_include('plugins'); + return ctools_get_plugins('ctools', 'style_bases'); +} + +/** + * Fetch metadata about all of the style base types that are available. + */ +function ctools_get_style_base_types() { + $types = array(); + foreach (module_implements('ctools_style_base_types') as $module) { + $types[$module] = module_invoke($module, 'ctools_style_base_types'); + } + + return $types; +} + +/** + * Render the icon for a style base. + */ +function ctools_stylizer_print_style_icon($plugin, $print_title = TRUE) { + $file = $plugin['path'] . '/' . $plugin['icon']; + $title = $print_title ? $plugin['title'] : ''; + return theme('ctools_style_icon', theme('image', $file), $title); +} + +/** + * Theme the style icon image + */ +function theme_ctools_style_icon($image, $title = NULL) { + ctools_add_css('stylizer'); + ctools_add_js('stylizer'); + $output = '<div class="ctools-style-icon">'; + $output .= $image; + if ($title) { + $output .= '<div class="caption">' . $title . '</div>'; + } + $output .= '</div>'; + return $output; +} + +/** + * Add the necessary CSS for a stylizer plugin to the page. + * + * This will check to see if the images directory and the cached CSS + * exists and, if not, will regenerate everything needed. + */ +function ctools_stylizer_add_css($plugin, $settings) { + if (!file_exists(ctools_stylizer_get_image_path($plugin, $settings, FALSE))) { + ctools_stylizer_build_style($plugin, $settings, TRUE); + return; + } + + ctools_include('css'); + $filename = ctools_css_retrieve(ctools_stylizer_get_css_id($plugin, $settings)); + if (!$filename) { + ctools_stylizer_build_style($plugin, $settings, TRUE); + } + else { + ctools_css_add_css($filename); + } +} + +/** + * Build the files for a stylizer given the proper settings. + */ +function ctools_stylizer_build_style($plugin, $settings, $add_css = FALSE) { + $path = ctools_stylizer_get_image_path($plugin, $settings); + if (!$path) { + return; + } + + $replacements = array(); + + // Set up palette conversions + foreach ($settings['palette'] as $key => $color) { + $replacements['%' . $key ] = $color; + } + + // Process image actions: + if (!empty($plugin['actions'])) { + $processor = new ctools_stylizer_image_processor; + $processor->execute($path, $plugin, $settings); + +// @todo -- there needs to be an easier way to get at this. +// dsm($processor->message_log); + // Add filenames to our conversions. + } + + // Convert and write the CSS file. + $css = file_get_contents($plugin['path'] . '/' . $plugin['css']); + + // Replace %style keyword with our generated class name. + // @todo We need one more unique identifier I think. + $class = ctools_stylizer_get_css_class($plugin, $settings); + $replacements['%style'] = '.' . $class; + + if (!empty($processor) && !empty($processor->paths)) { + foreach ($processor->paths as $file => $image) { + $replacements[$file] = file_create_url($image); + } + } + + if (!empty($plugin['build']) && function_exists($plugin['build'])) { + $plugin['build']($plugin, $settings, $css, $replacements); + } + + $css = strtr($css, $replacements); + ctools_include('css'); + $filename = ctools_css_store(ctools_stylizer_get_css_id($plugin, $settings), $css, FALSE); + + if ($add_css) { + ctools_css_add_css($filename); + } +} + +/** + * Clean up no longer used files. + * + * To prevent excess clutter in the files directory, this should be called + * whenever a style is going out of use. When being deleted, but also when + * the palette is being changed. + */ +function ctools_stylizer_cleanup_style($plugin, $settings) { + ctools_include('css'); + $path = ctools_stylizer_get_image_path($plugin, $settings, FALSE); + if ($path) { + ctools_stylizer_recursive_delete($path); + } + + ctools_css_clear(ctools_stylizer_get_css_id($plugin, $settings)); +} + +/** + * Recursively delete all files and folders in the specified filepath, then + * delete the containing folder. + * + * Note that this only deletes visible files with write permission. + * + * @param string $path + * A filepath relative to file_directory_path. + */ +function ctools_stylizer_recursive_delete($path) { + if (empty($path)) { + return; + } + + $listing = $path . '/*'; + + foreach (glob($listing) as $file) { + if (is_file($file) === TRUE) { + @unlink($file); + } + elseif (is_dir($file) === TRUE) { + ctools_stylizer_recursive_delete($file); + } + } + + @rmdir($path); +} + +/** + * Get a safe name for the settings. + * + * This uses an md5 of the palette if the name is temporary so + * that multiple temporary styles on the same page can coexist + * safely. + */ +function ctools_stylizer_get_settings_name($settings) { + if ($settings['name'] != '_temporary') { + return $settings['name']; + } + + return $settings['name'] . '-' . md5(serialize($settings['palette'])); +} + +/** + * Get the path where images will be stored for a given style plugin and settings. + * + * This function will make sure the path exists. + */ +function ctools_stylizer_get_image_path($plugin, $settings, $check = TRUE) { + $file = 'ctools/style/' . $settings['name'] . '/' . md5(serialize($settings['palette'])); + $path = file_create_path($file); + + if ($check && !ctools_file_check_directory($path)) { + $base = ''; + foreach (explode('/', $file) as $bit) { + $base .= '/' . $bit; + $path = file_directory_path() . $base; + if (!ctools_file_check_directory($path, FILE_CREATE_DIRECTORY)) { + drupal_set_message(t('Unable to create CTools styles cache directory @path. Check the permissions on your files directory.', array('@path' => $path)), 'error'); + return; + } + } + } + + return $path; +} + +/** + * Get the id used to cache CSS for a given style plugin and settings. + */ +function ctools_stylizer_get_css_id($plugin, $settings) { + return 'ctools-stylizer:' . $settings['name'] . ':' . md5(serialize($settings['palette'])); +} + +/** + * Get the class to use for a stylizer plugin. + */ +function ctools_stylizer_get_css_class($plugin, $settings) { + ctools_include('cleanstring'); + return ctools_cleanstring($plugin['name'] . '-' . ctools_stylizer_get_settings_name($settings)); +} + +class ctools_stylizer_image_processor { + var $workspace = NULL; + var $name = NULL; + + var $workspaces = array(); + + var $message_log = array(); + var $error_log = array(); + + function execute($path, $plugin, $settings) { + $this->path = $path; + $this->plugin = $plugin; + $this->settings = $settings; + $this->palette = $settings['palette']; + + if (is_string($plugin['actions']) && function_exists($plugin['actions'])) { + $actions = $plugin['actions']($plugin, $settings); + } + else if (is_array($plugin['actions'])) { + $actions = $plugin['actions']; + } + + if (!empty($actions) && is_array($actions)) { + foreach ($plugin['actions'] as $action) { + $command = 'command_' . array_shift($action); + if (method_exists($this, $command)) { + call_user_func_array(array($this, $command), $action); + } + } + } + + // Clean up buffers. + foreach ($this->workspaces as $name => $workspace) { + imagedestroy($this->workspaces[$name]); + } + } + + function log($message, $type = 'normal') { + $this->message_log[] = $message; + if ($type == 'error') { + $this->error_log[] = $message; + } + } + + function set_current_workspace($workspace) { + $this->log("Set current workspace: $workspace"); + $this->workspace = &$this->workspaces[$workspace]; + $this->name = $workspace; + } + + /** + * Create a new workspace. + */ + function command_new($name, $width, $height) { + $this->log("New workspace: $name ($width x $height)"); + // Clean up if there was already a workspace there. + if (isset($this->workspaces[$name])) { + imagedestroy($this->workspaces[$name]); + } + + $this->workspaces[$name] = imagecreatetruecolor($width, $height); + $this->set_current_workspace($name); + + // Make sure the new workspace has a transparent color. + + // Turn off transparency blending (temporarily) + imagealphablending($this->workspace, FALSE); + + // Create a new transparent color for image + $color = imagecolorallocatealpha($this->workspace, 0, 0, 0, 127); + + // Completely fill the background of the new image with allocated color. + imagefill($this->workspace, 0, 0, $color); + + // Restore transparency blending + imagesavealpha($this->workspace, TRUE); + + } + + /** + * Create a new workspace a file. + * + * This will make the new workspace the current workspace. + */ + function command_load($name, $file) { + $this->log("New workspace: $name (from $file)"); + if (!file_exists($file)) { + // Try it relative to the plugin + $file = $this->plugin['path'] . '/' . $file; + if (!file_exists($file)) { + $this->log("Unable to open $file"); + return; + } + } + + // Clean up if there was already a workspace there. + if (isset($this->workspaces[$name])) { + imagedestroy($this->workspaces[$name]); + } + + $this->workspaces[$name] = imagecreatefrompng($file); + $this->set_current_workspace($name); + } + + /** + * Create a new workspace using the properties of an existing workspace + */ + function command_new_from($name, $workspace) { + $this->log("New workspace: $name from existing $workspace"); + if (empty($this->workspaces[$workspace])) { + $this->log("Workspace $name does not exist.", 'error'); + return; + } + + // Clean up if there was already a workspace there. + if (isset($this->workspaces[$name])) { + imagedestroy($this->workspaces[$name]); + } + + $this->workspaces[$name] = $this->new_image($this->workspace[$workspace]); + $this->set_current_workspace($name); + } + + /** + * Set the current workspace. + */ + function command_workspace($name) { + $this->log("Set workspace: $name"); + if (empty($this->workspaces[$name])) { + $this->log("Workspace $name does not exist.", 'error'); + return; + } + $this->set_current_workspace($name); + } + + /** + * Copy the contents of one workspace into the current workspace. + */ + function command_merge_from($workspace, $x = 0, $y = 0) { + $this->log("Merge from: $workspace ($x, $y)"); + if (empty($this->workspaces[$workspace])) { + $this->log("Workspace $name does not exist.", 'error'); + return; + } + + $this->merge($this->workspaces[$workspace], $this->workspace, $x, $y); + } + + function command_merge_to($workspace, $x = 0, $y = 0) { + $this->log("Merge to: $workspace ($x, $y)"); + if (empty($this->workspaces[$workspace])) { + $this->log("Workspace $name does not exist.", 'error'); + return; + } + + $this->merge($this->workspace, $this->workspaces[$workspace], $x, $y); + $this->set_current_workspace($workspace); + } + + /** + * Blend an image into the current workspace. + */ + function command_merge_from_file($file, $x = 0, $y = 0) { + $this->log("Merge from file: $file ($x, $y)"); + if (!file_exists($file)) { + // Try it relative to the plugin + $file = $this->plugin['path'] . '/' . $file; + if (!file_exists($file)) { + $this->log("Unable to open $file"); + return; + } + } + + $source = imagecreatefrompng($file); + + $this->merge($source, $this->workspace, $x, $y); + + imagedestroy($source); + } + + function command_fill($color, $x, $y, $width, $height) { + $this->log("Fill: $color ($x, $y, $width, $height)"); + imagefilledrectangle($this->workspace, $x, $y, $x + $width, $y + $height, ctools_color_gd($this->workspace, $this->palette[$color])); + } + + function command_gradient($from, $to, $x, $y, $width, $height, $direction = 'down') { + $this->log("Gradient: $from to $to ($x, $y, $width, $height) $direction"); + + if ($direction == 'down') { + for ($i = 0; $i < $height; ++$i) { + $color = ctools_color_blend($this->workspace, $this->palette[$from], $this->palette[$to], $i / ($height - 1)); + imagefilledrectangle($this->workspace, $x, $y + $i, $x + $width, $y + $i + 1, $color); + } + } + else { + for ($i = 0; $i < $width; ++$i) { + $color = ctools_color_blend($this->workspace, $this->palette[$from], $this->palette[$to], $i / ($width - 1)); + imagefilledrectangle($this->workspace, $x + $i, $y, $x + $i + 1, $y + $height, $color); + } + } + } + + /** + * Colorize the current workspace with the given location. + * + * This uses simple color blending to colorize the image. + * + * @todo it is possible that this colorize could allow different methods for + * determining how to blend colors? + */ + function command_colorize($color, $x = NULL, $y = NULL, $width = NULL, $height = NULL) { + if (!isset($x)) { + $whole_image = TRUE; + $x = $y = 0; + $width = imagesx($this->workspace); + $height = imagesy($this->workspace); + } + $this->log("Colorize: $color ($x, $y, $width, $height)"); + + $c = ctools_color_unpack($this->palette[$color]); + + imagealphablending($this->workspace, FALSE); + imagesavealpha($this->workspace, TRUE); + + // If PHP 5 use the nice imagefilter which is faster. + if (!empty($whole_image) && version_compare(phpversion(), '5.2.5', '>=') && function_exists('imagefilter')) { + imagefilter($this->workspace, IMG_FILTER_COLORIZE, $c[0], $c[1], $c[2]); + } + else { + // Otherwise we can do it the brute force way. + for ($j = 0; $j < $height; $j++) { + for ($i = 0; $i < $width; $i++) { + $current = imagecolorsforindex($this->workspace, imagecolorat($this->workspace, $i, $j)); + $new_index = imagecolorallocatealpha($this->workspace, $c[0], $c[1], $c[2], $current['alpha']); + imagesetpixel($this->workspace, $i, $j, $new_index); + } + } + } + } + + /** + * Colorize the current workspace with the given location. + * + * This uses a color replacement algorithm that retains luminosity but + * turns replaces all color with the specified color. + */ + function command_hue($color, $x = NULL, $y = NULL, $width = NULL, $height = NULL) { + if (!isset($x)) { + $whole_image = TRUE; + $x = $y = 0; + $width = imagesx($this->workspace); + $height = imagesy($this->workspace); + } + $this->log("Hue: $color ($x, $y, $width, $height)"); + + list($red, $green, $blue) = ctools_color_unpack($this->palette[$color]); + + // We will create a monochromatic palette based on the input color + // which will go from black to white. + + // Input color luminosity: this is equivalent to the position of the + // input color in the monochromatic palette + $luminosity_input = round(255 * ($red + $green + $blue) / 765); // 765 = 255 * 3 + + // We fill the palette entry with the input color at itscorresponding position + $palette[$luminosity_input]['red'] = $red; + $palette[$luminosity_input]['green'] = $green; + $palette[$luminosity_input]['blue'] = $blue; + + // Now we complete the palette, first we'll do it tothe black, and then to + // the white. + + // From input to black + $steps_to_black = $luminosity_input; + + // The step size for each component + if ($steps_to_black) { + $step_size_red = $red / $steps_to_black; + $step_size_green = $green / $steps_to_black; + $step_size_blue = $blue / $steps_to_black; + + for ($i = $steps_to_black; $i >= 0; $i--) { + $palette[$steps_to_black-$i]['red'] = $red - round($step_size_red * $i); + $palette[$steps_to_black-$i]['green'] = $green - round($step_size_green * $i); + $palette[$steps_to_black-$i]['blue'] = $blue - round($step_size_blue * $i); + } + } + + // From input to white + $steps_to_white = 255 - $luminosity_input; + + if ($steps_to_white) { + $step_size_red = (255 - $red) / $steps_to_white; + $step_size_green = (255 - $green) / $steps_to_white; + $step_size_blue = (255 - $blue) / $steps_to_white; + } + else { + $step_size_red=$step_size_green=$step_size_blue=0; + } + + // The step size for each component + for($i = ($luminosity_input + 1); $i <= 255; $i++) { + $palette[$i]['red'] = $red + round($step_size_red * ($i - $luminosity_input)); + $palette[$i]['green'] = $green + round($step_size_green * ($i - $luminosity_input)); + $palette[$i]['blue']= $blue + round($step_size_blue * ($i - $luminosity_input)); + } + + // Go over the specified area of the image and update the colors. + for ($j = $x; $j < $height; $j++) { + for ($i = $y; $i < $width; $i++) { + $color = imagecolorsforindex($this->workspace, imagecolorat($this->workspace, $i, $j)); + $luminosity = round(255 * ($color['red'] + $color['green'] + $color['blue']) / 765); + $new_color = imagecolorallocatealpha($this->workspace, $palette[$luminosity]['red'], $palette[$luminosity]['green'], $palette[$luminosity]['blue'], $color['alpha']); + imagesetpixel($this->workspace, $i, $j, $new_color); + } + } + } + + /** + * Take a slice out of the current workspace and save it as an image. + */ + function command_slice($file, $x = NULL, $y = NULL, $width = NULL, $height = NULL) { + if (!isset($x)) { + $x = $y = 0; + $width = imagesx($this->workspace); + $height = imagesy($this->workspace); + } + + $this->log("Slice: $file ($x, $y, $width, $height)"); + + $base = basename($file); + $image = $this->path . '/' . $base; + + $slice = $this->new_image($this->workspace, $width, $height); + imagecopy($slice, $this->workspace, 0, 0, $x, $y, $width, $height); + + // Make sure alphas are saved: + imagealphablending($slice, FALSE); + imagesavealpha($slice, TRUE); + + // Save image. + imagepng($slice, $image); + imagedestroy($slice); + + // Set standard file permissions for webserver-generated files + @chmod(realpath($image), 0664); + + $this->paths[$file] = $image; + } + + /** + * Prepare a new image for being copied or worked on, preserving transparency. + */ + function &new_image(&$source, $width = NULL, $height = NULL) { + if (!isset($width)) { + $width = imagesx($source); + } + + if (!isset($height)) { + $height = imagesy($source); + } + + $target = imagecreatetruecolor($width, $height); + imagealphablending($target, FALSE); + imagesavealpha($target, TRUE); + + $transparency_index = imagecolortransparent($source); + + // If we have a specific transparent color + if ($transparency_index >= 0) { + // Get the original image's transparent color's RGB values + $transparent_color = imagecolorsforindex($source, $transparency_index); + + // Allocate the same color in the new image resource + $transparency_index = imagecolorallocate($target, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']); + + // Completely fill the background of the new image with allocated color. + imagefill($target, 0, 0, $transparency_index); + + // Set the background color for new image to transparent + imagecolortransparent($target, $transparency_index); + } + // Always make a transparent background color for PNGs that don't have one allocated already + else { + // Create a new transparent color for image + $color = imagecolorallocatealpha($target, 0, 0, 0, 127); + + // Completely fill the background of the new image with allocated color. + imagefill($target, 0, 0, $color); + } + + return $target; + } + + /** + * Merge two images together, preserving alpha transparency. + */ + function merge(&$from, &$to, $x, $y) { + // Blend over template. + $width = imagesx($from); + $height = imagesy($from); + + // Re-enable alpha blending to make sure transparency merges. + imagealphablending($to, TRUE); + imagecopy($to, $from, $x, $y, 0, 0, $width, $height); + imagealphablending($to, FALSE); + } +} + +/** + * Get the cached changes to a given task handler. + */ +function ctools_stylizer_get_settings_cache($name) { + ctools_include('object-cache'); + return ctools_object_cache_get('ctools_stylizer_settings', $name); +} + +/** + * Store changes to a task handler in the object cache. + */ +function ctools_stylizer_set_settings_cache($name, $settings) { + ctools_include('object-cache'); + ctools_object_cache_set('ctools_stylizer_settings', $name, $settings); +} + +/** + * Remove an item from the object cache. + */ +function ctools_stylizer_clear_settings_cache($name) { + ctools_include('object-cache'); + ctools_object_cache_clear('ctools_stylizer_settings', $name); +} + +/** + * Add a new style of the specified type. + */ +function ctools_stylizer_edit_style(&$info, $js, $step = NULL) { + $name = '::new'; + $form_info = array( + 'id' => 'ctools_stylizer_edit_style', + 'path' => $info['path'], + 'show trail' => TRUE, + 'show back' => TRUE, + 'show return' => FALSE, + 'next callback' => 'ctools_stylizer_edit_style_next', + 'finish callback' => 'ctools_stylizer_edit_style_finish', + 'return callback' => 'ctools_stylizer_edit_style_finish', + 'cancel callback' => 'ctools_stylizer_edit_style_cancel', + 'forms' => array( + 'choose' => array( + 'form id' => 'ctools_stylizer_edit_style_form_choose', + ), + ), + ); + + if (empty($info['settings'])) { + $form_info['order'] = array( + 'choose' => t('Select base style'), + ); + if (empty($step)) { + $step = 'choose'; + } + + if ($step != 'choose') { + $cache = ctools_stylizer_get_settings_cache($name); + if (!$cache) { + $output = t('Missing settings cache.'); + if ($js) { + return ctools_modal_form_render($form_state, $output); + } + else { + return $output; + } + } + + if (!empty($cache['owner settings'])) { + $info['owner settings'] = $cache['owner settings']; + } + $settings = $cache['settings']; + } + else { + $settings = array( + 'name' => '_temporary', + 'style_base' => NULL, + 'palette' => array(), + ); + ctools_stylizer_clear_settings_cache($name); + } + $op = 'add'; + } + else { + $cache = ctools_stylizer_get_settings_cache($info['settings']['name']); + + if (!empty($cache)) { + if (!empty($cache['owner settings'])) { + $info['owner settings'] = $cache['owner settings']; + } + $settings = $cache['settings']; + } + else { + $settings = $info['settings']; + } + $op = 'edit'; + } + + if (!empty($info['op'])) { + // Allow this to override. Necessary to allow cloning properly. + $op = $info['op']; + } + + $plugin = NULL; + if (!empty($settings['style_base'])) { + $plugin = ctools_get_style_base($settings['style_base']); + $info['type'] = $plugin['type']; + ctools_stylizer_add_plugin_forms($form_info, $plugin, $op); + } + else { + // This is here so the 'finish' button does not show up, and because + // we don't have the selected style we don't know what the next form(s) + // will be. + $form_info['order']['next'] = t('Configure style'); + } + + if (count($form_info['order']) < 2 || $step == 'choose') { + $form_info['show trail'] = FALSE; + } + + $form_state = array( + 'module' => $info['module'], + 'type' => $info['type'], + 'owner info' => &$info, + 'plugin' => $plugin, + 'name' => $name, + 'step' => $step, + 'settings' => $settings, + 'ajax' => $js, + 'op' => $op, + ); + + if (!empty($info['modal'])) { + $form_state['modal'] = TRUE; + $form_state['title'] = $info['modal']; + $form_state['modal return'] = TRUE; + } + + ctools_include('wizard'); + $output = ctools_wizard_multistep_form($form_info, $step, $form_state); + + if (!empty($form_state['complete'])) { + $info['complete'] = TRUE; + $info['settings'] = $form_state['settings']; + } + + if ($js && !$output && !empty($form_state['clicked_button']['#next'])) { + // We have to do a separate redirect here because the formula that adds + // stuff to the wizard after being chosen hasn't happened. The wizard + // tried to go to the next step which did not exist. + return ctools_stylizer_edit_style($info, $js, $form_state['clicked_button']['#next']); + } + + if ($js) { + return ctools_modal_form_render($form_state, $output); + } + else { + return $output; + } +} + +/** + * Add wizard forms specific to a style base plugin. + * + * The plugin can store forms either as a simple 'edit form' + * => 'form callback' or if it needs the more complicated wizard + * functionality, it can set 'forms' and 'order' with values suitable + * for the wizard $form_info array. + * + * @param &$form_info + * The form info to modify. + * @param $plugin + * The plugin to use. + * @param $op + * Either 'add' or 'edit' so we can get the right forms. + */ +function ctools_stylizer_add_plugin_forms(&$form_info, $plugin, $op) { + if (empty($plugin['forms'])) { + if ($op == 'add' && isset($plugin['add form'])) { + $id = $plugin['add form']; + } + else if (isset($plugin['edit form'])) { + $id = $plugin['edit form']; + } + else { + $id = 'ctools_stylizer_edit_style_form_default'; + } + + $form_info['forms']['settings'] = array( + 'form id' => $id, + ); + $form_info['order']['settings'] = t('Settings'); + } + else { + $form_info['forms'] += $plugin['forms']; + $form_info['order'] += $plugin['order']; + } +} + +/** + * Callback generated when the add style process is finished. + */ +function ctools_stylizer_edit_style_finish(&$form_state) { + $form_state['complete'] = TRUE; + ctools_stylizer_clear_settings_cache($form_state['name']); + + if (isset($form_state['settings']['old_settings'])) { + unset($form_state['settings']['old_settings']); + } +} + +/** + * Callback generated when the 'next' button is clicked. + */ +function ctools_stylizer_edit_style_next(&$form_state) { + $form_state['form_info']['path'] = str_replace('%name', $form_state['name'], $form_state['form_info']['path']); + $form_state['redirect'] = ctools_wizard_get_path($form_state['form_info'], $form_state['clicked_button']['#next']); + + // Update the cache with changes. + $cache = array('settings' => $form_state['settings']); + if (!empty($form_state['owner info']['owner settings'])) { + $cache['owner settings'] = $form_state['owner info']['owner settings']; + } + ctools_stylizer_set_settings_cache($form_state['name'], $cache); +} + +/** + * Callback generated when the 'cancel' button is clicked. + * + * We might have some temporary data lying around. We must remove it. + */ +function ctools_stylizer_edit_style_cancel(&$form_state) { + if (!empty($form_state['name'])) { + ctools_stylizer_clear_settings_cache($form_state['name']); + } +} + +/** + * Choose which plugin to use to create a new style. + */ +function ctools_stylizer_edit_style_form_choose(&$form, &$form_state) { + $plugins = ctools_get_style_bases(); + $options = array(); + + $categories = array(); + foreach ($plugins as $name => $plugin) { + if ($form_state['module'] == $plugin['module'] && $form_state['type'] == $plugin['type']) { + $categories[$plugin['category']] = $plugin['category']; + $unsorted_options[$plugin['category']][$name] = ctools_stylizer_print_style_icon($plugin, TRUE); + } + } + + asort($categories); + + foreach ($categories as $category) { + $options[$category] = $unsorted_options[$category]; + } + + $form['style_base'] = array( + '#prefix' => '<div class="ctools-style-icons clear-block">', + '#suffix' => '</div>', + ); + + ctools_include('cleanstring'); + foreach ($options as $category => $radios) { + $cat = ctools_cleanstring($category); + $form['style_base'][$cat] = array( + '#prefix' => '<div class="ctools-style-category clear-block"><label>' . $category . '</label>', + '#suffix' => '</div>', + ); + + foreach ($radios as $key => $choice) { + // Generate the parents as the autogenerator does, so we will have a + // unique id for each radio button. + $form['style_base'][$cat][$key] = array( + '#type' => 'radio', + '#title' => $choice, + '#parents' => array('style_base'), + '#id' => form_clean_id('edit-style-base-' . $key), + '#return_value' => check_plain($key), + ); + } + } +} + +function ctools_stylizer_edit_style_form_choose_submit(&$form, &$form_state) { + $form_state['settings']['style_base'] = $form_state['values']['style_base']; + + // The 'next' form will show up as 'next' but that's not accurate now that + // we have a style. Figure out what next really is and update. + $plugin = ctools_get_style_base($form_state['settings']['style_base']); + if (empty($plugin['forms'])) { + $form_state['clicked_button']['#next'] = 'settings'; + } + else { + $forms = array_keys($form_info['forms']); + $form_state['clicked_button']['#next'] = array_shift($forms); + } + + // Fill in the defaults for the settings. + if (!empty($plugin['defaults'])) { + // @todo allow a callback + $form_state['settings'] += $plugin['defaults']; + } +} + +/** + * The default stylizer style editing form. + * + * Even when not using this, styles should call through to this form in + * their own edit forms. + */ +function ctools_stylizer_edit_style_form_default(&$form, &$form_state) { + ctools_add_js('stylizer'); + ctools_add_css('stylizer'); + drupal_add_js('misc/farbtastic/farbtastic.js'); + drupal_add_css('misc/farbtastic/farbtastic.css'); + + $plugin = &$form_state['plugin']; + $settings = &$form_state['settings']; + + $form['top box'] = array( + '#prefix' => '<div id="ctools-stylizer-top-box" class="clear-block">', + '#suffix' => '</div>', + ); + $form['top box']['left'] = array( + '#prefix' => '<div id="ctools-stylizer-left-box">', + '#suffix' => '</div>', + ); + $form['top box']['preview'] = array( + // We have a copy of the $form_state on $form because form theme functions + // do not get $form_state. + '#theme' => 'ctools_stylizer_preview_form', + '#form_state' => &$form_state, + ); + + $form['top box']['preview']['submit'] = array( + '#type' => 'submit', + '#value' => t('Preview'), + ); + + if (!empty($plugin['palette'])) { + $form['top box']['color'] = array( + '#type' => 'fieldset', + '#title' => t('Color scheme'), + '#attributes' => array('id' => 'ctools_stylizer_color_scheme_form', 'class' => 'ctools-stylizer-color-edit'), + '#theme' => 'ctools_stylizer_color_scheme_form', + ); + + $form['top box']['color']['palette']['#tree'] = true; + + foreach ($plugin['palette'] as $key => $color) { + if (empty($settings['palette'][$key])) { + $settings['palette'][$key] = $color['default_value']; + } + + $form['top box']['color']['palette'][$key] = array( + '#type' => 'textfield', + '#title' => $color['label'], + '#default_value' => $settings['palette'][$key], + '#size' => 8, + ); + } + } + + if (!empty($plugin['settings form']) && function_exists($plugin['settings form'])) { + $plugin['settings form']($form, $form_state); + } + + if (!empty($form_state['owner info']['owner form']) && function_exists($form_state['owner info']['owner form'])) { + $form_state['owner info']['owner form']($form, $form_state); + } +} + +/** + * Theme the stylizer color scheme form. + */ +function theme_ctools_stylizer_color_scheme_form($form) { + $output = ''; + + // Wrapper + $output .= '<div class="color-form clear-block">'; + + // Color schemes +// $output .= drupal_render($form['scheme']); + + // Palette + $output .= '<div id="palette" class="clear-block">'; + foreach (element_children($form['palette']) as $name) { + $output .= drupal_render($form['palette'][$name]); + } + $output .= '</div>'; // palette + + $output .= '</div>'; // color form + + return $output; +} + +/** + * Theme the stylizer preview form. + */ +function theme_ctools_stylizer_preview_form($form) { + $plugin = $form['#form_state']['plugin']; + $settings = $form['#form_state']['settings']; + + if (!empty($form['#form_state']['settings']['old_settings'])) { + ctools_stylizer_cleanup_style($plugin, $form['#form_state']['settings']['old_settings']); + } + $preview = ''; + if (!empty($plugin['preview'])) { + $preview = $plugin['preview']; + } + else { + $base_types = ctools_get_style_base_types(); + if (!empty($base_types[$plugin['module']][$plugin['type']]['preview'])) { + $preview = $base_types[$plugin['module']][$plugin['type']]['preview']; + } + } + + if (!empty($preview) && function_exists($preview)) { + $output = '<fieldset id="preview"><legend>' . t('Preview') . '</legend>'; + $output .= $preview($plugin, $settings); + $output .= drupal_render($form); + $output .= '</fieldset>'; + + return $output; + } +} + +function ctools_stylizer_edit_style_form_default_validate($form, &$form_state) { + if (!empty($form_state['owner info']['owner form validate']) && function_exists($form_state['owner info']['owner form validate'])) { + $form_state['owner info']['owner form validate']($form, $form_state); + } + + if (!empty($form_state['plugin']['settings form validate']) && function_exists($form_state['plugin']['settings form validate'])) { + $form_state['plugin']['settings form validate']($form, $form_state); + } +} + +function ctools_stylizer_edit_style_form_default_submit($form, &$form_state) { + // Store old settings for the purposes of cleaning up. + $form_state['settings']['old_settings'] = $form_state['settings']; + $form_state['settings']['palette'] = $form_state['values']['palette']; + + if (!empty($form_state['owner info']['owner form submit']) && function_exists($form_state['owner info']['owner form submit'])) { + $form_state['owner info']['owner form submit']($form, $form_state); + } + + if (!empty($form_state['plugin']['settings form submit']) && function_exists($form_state['plugin']['settings form submit'])) { + $form_state['plugin']['settings form submit']($form, $form_state); + } + + if ($form_state['clicked_button']['#value'] == t('Preview')) { + $form_state['rerender'] = TRUE; + // Update the cache with changes. + if (!empty($form_state['name'])) { + $cache = array('settings' => $form_state['settings']); + if (!empty($form_state['owner info']['owner settings'])) { + $cache['owner settings'] = $form_state['owner info']['owner settings']; + } + ctools_stylizer_set_settings_cache($form_state['name'], $cache); + } + } +} + +// -------------------------------------------------------------------------- +// CSS forms and tools that plugins can use. + +/** + * Font selector form + */ +function ctools_stylizer_font_selector_form(&$form, &$form_state, $label, $settings) { + // Family + $form['#prefix'] = '<div class="ctools-stylizer-spacing-form clear-block">'; + $form['#type'] = 'fieldset'; + $form['#title'] = $label; + $form['#suffix'] = '</div>'; + $form['#tree'] = TRUE; + + $form['font'] = array( + '#title' => t('Font family'), + '#type' => 'select', + '#default_value' => isset($settings['font']) ? $settings['font'] : '', + '#options' => array( + '' => '', + 'Arial, Helvetica, sans-serif' => t('Arial, Helvetica, sans-serif'), + 'Times New Roman, Times, serif' => t('Times New Roman, Times, serif'), + 'Courier New, Courier, monospace' => t('Courier New, Courier, monospace'), + 'Georgia, Times New Roman, Times, serif' => t('Georgia, Times New Roman, Times, serif'), + 'Verdana, Arial, Helvetica, sans-serif' => t('Verdana, Arial, Helvetica, sans-serif'), + 'Geneva, Arial, Helvetica, sans-serif' => t('Geneva, Arial, Helvetica, sans-serif'), + 'Trebuchet MS, Trebuchet, Verdana, sans-serif' => t('Trebuchet MS, Trebuchet, Verdana, sans-serif'), + ), + ); + + // size + $form['size'] = array( + '#title' => t('Size'), + '#type' => 'select', + '#default_value' => isset($settings['size']) ? $settings['size'] : '', + '#options' => array( + '' => '', + 'xx-small' => t('XX-Small'), + 'x-small' => t('X-Small'), + 'small' => t('Small'), + 'medium' => t('Medium'), + 'large' => t('Large'), + 'x-large' => t('X-Large'), + 'xx-large' => t('XX-Large'), + ), + ); + + // letter spacing + $form['letter_spacing'] = array( + '#title' => t('Letter spacing'), + '#type' => 'select', + '#default_value' => isset($settings['letter_spacing']) ? $settings['letter_spacing'] : '', + '#options' => array( + '' => '', + "-10px" => '10px', + "-9px" => '9px', + "-8px" => '8px', + "-7px" => '7px', + "-6px" => '6px', + "-5px" => '5px', + "-4px" => '4px', + "-3px" => '3px', + "-2px" => '2px', + "-1px" => '1px', + "0" => '0', + "1px" => '1px', + "2px" => '2px', + "3px" => '3px', + "4px" => '4px', + "5px" => '5px', + "6px" => '6px', + "7px" => '7px', + "8px" => '8px', + "9px" => '9px', + "10px" => '10px', + "11px" => '11px', + "12px" => '12px', + "13px" => '13px', + "14px" => '14px', + "15px" => '15px', + "16px" => '16px', + "17px" => '17px', + "18px" => '18px', + "19px" => '19px', + "20px" => '20px', + "21px" => '21px', + "22px" => '22px', + "23px" => '23px', + "24px" => '24px', + "25px" => '25px', + "26px" => '26px', + "27px" => '27px', + "28px" => '28px', + "29px" => '29px', + "30px" => '30px', + "31px" => '31px', + "32px" => '32px', + "33px" => '33px', + "34px" => '34px', + "35px" => '35px', + "36px" => '36px', + "37px" => '37px', + "38px" => '38px', + "39px" => '39px', + "40px" => '40px', + "41px" => '41px', + "42px" => '42px', + "43px" => '43px', + "44px" => '44px', + "45px" => '45px', + "46px" => '46px', + "47px" => '47px', + "48px" => '48px', + "49px" => '49px', + "50px" => '50px', + ), + ); + + // word space + $form['word_spacing'] = array( + '#title' => t('Word spacing'), + '#type' => 'select', + '#default_value' => isset($settings['word_spacing']) ? $settings['word_spacing'] : '', + '#options' => array( + '' => '', + "-1em" => '-1em', + "-0.95em" => '-0.95em', + "-0.9em" => '-0.9em', + "-0.85em" => '-0.85em', + "-0.8em" => '-0.8em', + "-0.75em" => '-0.75em', + "-0.7em" => '-0.7em', + "-0.65em" => '-0.65em', + "-0.6em" => '-0.6em', + "-0.55em" => '-0.55em', + "-0.5em" => '-0.5em', + "-0.45em" => '-0.45em', + "-0.4em" => '-0.4em', + "-0.35em" => '-0.35em', + "-0.3em" => '-0.3em', + "-0.25em" => '-0.25em', + "-0.2em" => '-0.2em', + "-0.15em" => '-0.15em', + "-0.1em" => '-0.1em', + "-0.05em" => '-0.05em', + "normal" => 'normal', + "0.05em" => '0.05em', + "0.1em" => '0.1em', + "0.15em" => '0.15em', + "0.2em" => '0.2em', + "0.25em" => '0.25em', + "0.3em" => '0.3em', + "0.35em" => '0.35em', + "0.4em" => '0.4em', + "0.45em" => '0.45em', + "0.5em" => '0.5em', + "0.55em" => '0.55em', + "0.6em" => '0.6em', + "0.65em" => '0.65em', + "0.7em" => '0.7em', + "0.75em" => '0.75em', + "0.8em" => '0.8em', + "0.85em" => '0.85em', + "0.9em" => '0.9em', + "0.95em" => '0.95em', + "1em" => '1em', + ), + ); + + // decoration + $form['decoration'] = array( + '#title' => t('Decoration'), + '#type' => 'select', + '#default_value' => isset($settings['decoration']) ? $settings['decoration'] : '', + '#options' => array( + '' => '', + 'none' => t('None'), + 'underline' => t('Underline'), + 'overline' => t('Overline'), + 'line-through' => t('Line-through'), + ), + ); + + // weight + $form['weight'] = array( + '#title' => t('Weight'), + '#type' => 'select', + '#default_value' => isset($settings['weight']) ? $settings['weight'] : '', + '#options' => array( + '' => '', + 'normal' => t('Normal'), + 'bold' => t('Bold'), + 'bolder' => t('Bolder'), + 'lighter' => t('Lighter'), + ), + ); + + // style + $form['style'] = array( + '#title' => t('Style'), + '#type' => 'select', + '#default_value' => isset($settings['style']) ? $settings['style'] : '', + '#options' => array( + '' => '', + 'normal' => t('Normal'), + 'italic' => t('Italic'), + 'oblique' => t('Oblique'), + ), + ); + + // variant + $form['variant'] = array( + '#title' => t('Variant'), + '#type' => 'select', + '#default_value' => isset($settings['variant']) ? $settings['variant'] : '', + '#options' => array( + '' => '', + 'normal' => t('Normal'), + 'small-caps' => t('Small-caps'), + ), + ); + + // case + $form['case'] = array( + '#title' => t('Case'), + '#type' => 'select', + '#default_value' => isset($settings['case']) ? $settings['case'] : '', + '#options' => array( + '' => '', + 'capitalize' => t('Capitalize'), + 'uppercase' => t('Uppercase'), + 'lowercase' => t('Lowercase'), + 'none' => t('None'), + ), + ); + + // alignment + $form['alignment'] = array( + '#title' => t('Align'), + '#type' => 'select', + '#default_value' => isset($settings['alignment']) ? $settings['alignment'] : '', + '#options' => array( + '' => '', + 'justify' => t('Justify'), + 'left' => t('Left'), + 'right' => t('Right'), + 'center' => t('Center'), + ), + ); +} + +/** + * Copy font selector information into the settings + */ +function ctools_stylizer_font_selector_form_submit(&$form, &$form_state, &$values, &$settings) { + $settings = $values; +} + +function ctools_stylizer_font_apply_style(&$stylesheet, $selector, $settings) { + $css = ''; + if (isset($settings['font']) && $settings['font'] !== '') { + $css .= ' font-family: ' . $settings['font'] . ";\n"; + } + + if (isset($settings['size']) && $settings['size'] !== '') { + $css .= ' font-size: ' . $settings['size'] . ";\n"; + } + + if (isset($settings['weight']) && $settings['weight'] !== '') { + $css .= ' font-weight: ' . $settings['weight'] . ";\n"; + } + + if (isset($settings['style']) && $settings['style'] !== '') { + $css .= ' font-style: ' . $settings['style'] . ";\n"; + } + + if (isset($settings['variant']) && $settings['variant'] !== '') { + $css .= ' font-variant: ' . $settings['variant'] . ";\n"; + } + + if (isset($settings['case']) && $settings['case'] !== '') { + $css .= ' text-transform: ' . $settings['case'] . ";\n"; + } + + if (isset($settings['decoration']) && $settings['decoration'] !== '') { + $css .= ' text-decoration: ' . $settings['decoration'] . ";\n"; + } + + if (isset($settings['alignment']) && $settings['alignment'] !== '') { + $css .= ' text-align: ' . $settings['alignment'] . ";\n"; + } + + if (isset($settings['letter_spacing']) && $settings['letter_spacing'] !== '') { + $css .= ' letter-spacing: ' . $settings['letter_spacing'] . ";\n"; + } + + if (isset($settings['word_spacing']) && $settings['word_spacing'] !== '') { + $css .= ' word-spacing: ' . $settings['word_spacing'] . ";\n"; + } + + if ($css) { + $stylesheet .= $selector . " {\n" . $css . "}\n"; + } +} + +/** + * Border selector form + */ +function ctools_stylizer_border_selector_form(&$form, &$form_state, $label, $settings) { + // Family + $form['#prefix'] = '<div class="ctools-stylizer-spacing-form clear-block">'; + $form['#type'] = 'fieldset'; + $form['#title'] = $label; + $form['#suffix'] = '</div>'; + $form['#tree'] = TRUE; + + $form['thickness'] = array( + '#title' => t('Thickness'), + '#type' => 'select', + '#default_value' => isset($settings['thickness']) ? $settings['thickness'] : '', + '#options' => array( + '' => '', + "none" => t('None'), + "1px" => '1px', + "2px" => '2px', + "3px" => '3px', + "4px" => '4px', + "5px" => '5px', + ), + ); + + $form['style'] = array( + '#title' => t('style'), + '#type' => 'select', + '#default_value' => isset($settings['style']) ? $settings['style'] : '', + '#options' => array( + '' => '', + 'solid' => t('Solid'), + 'dotted' => t('Dotted'), + 'dashed' => t('Dashed'), + 'double' => t('Double'), + 'groove' => t('Groove'), + 'ridge' => t('Ridge'), + 'inset' => t('Inset'), + 'outset' => t('Outset'), + ), + ); +} + +/** + * Copy border selector information into the settings + */ +function ctools_stylizer_border_selector_form_submit(&$form, &$form_state, &$values, &$settings) { + $settings = $values; +} + +function ctools_stylizer_border_apply_style(&$stylesheet, $selector, $settings, $color, $which = NULL) { + $border = 'border'; + if ($which) { + $border .= '-' . $which; + } + + $css = ''; + if (isset($settings['thickness']) && $settings['thickness'] !== '') { + if ($settings['thickness'] == 'none') { + $css .= ' ' . $border . ': none'; + } + else { + $css .= ' ' . $border . '-width: ' . $settings['thickness'] . ";\n"; + + if (isset($settings['style']) && $settings['style'] !== '') { + $css .= ' ' . $border . '-style: ' . $settings['style'] . ";\n"; + } + + $css .= ' ' . $border . '-color: ' . $color . ";\n"; + } + } + + if ($css) { + $stylesheet .= $selector . " {\n" . $css . "}\n"; + } + +} + +/** + * padding selector form + */ +function ctools_stylizer_padding_selector_form(&$form, &$form_state, $label, $settings) { + // Family + $form['#prefix'] = '<div class="ctools-stylizer-spacing-form clear-block">'; + $form['#type'] = 'fieldset'; + $form['#title'] = $label; + $form['#suffix'] = '</div>'; + $form['#tree'] = TRUE; + + $options = array( + '' => '', + "0.05em" => '0.05em', + "0.1em" => '0.1em', + "0.15em" => '0.15em', + "0.2em" => '0.2em', + "0.25em" => '0.25em', + "0.3em" => '0.3em', + "0.35em" => '0.35em', + "0.4em" => '0.4em', + "0.45em" => '0.45em', + "0.5em" => '0.5em', + "0.55em" => '0.55em', + "0.6em" => '0.6em', + "0.65em" => '0.65em', + "0.7em" => '0.7em', + "0.75em" => '0.75em', + "0.8em" => '0.8em', + "0.85em" => '0.85em', + "0.9em" => '0.9em', + "0.95em" => '0.95em', + "1.0em" => '1.0em', + "1.05em" => '1.05em', + "1.1em" => '1.1em', + "1.15em" => '1.15em', + "1.2em" => '1.2em', + "1.25em" => '1.25em', + "1.3em" => '1.3em', + "1.35em" => '1.35em', + "1.4em" => '1.4em', + "1.45em" => '1.45em', + "1.5em" => '1.5em', + "1.55em" => '1.55em', + "1.6em" => '1.6em', + "1.65em" => '1.65em', + "1.7em" => '1.7em', + "1.75em" => '1.75em', + "1.8em" => '1.8em', + "1.85em" => '1.85em', + "1.9em" => '1.9em', + "1.95em" => '1.95em', + "2.0em" => '2.0em', + "2.05em" => '2.05em', + "2.1em" => '2.1em', + "2.15em" => '2.15em', + "2.2em" => '2.2em', + "2.25em" => '2.25em', + "2.3em" => '2.3em', + "2.35em" => '2.35em', + "2.4em" => '2.4em', + "2.45em" => '2.45em', + "2.5em" => '2.5em', + "2.55em" => '2.55em', + "2.6em" => '2.6em', + "2.65em" => '2.65em', + "2.7em" => '2.7em', + "2.75em" => '2.75em', + "2.8em" => '2.8em', + "2.85em" => '2.85em', + "2.9em" => '2.9em', + "2.95em" => '2.95em', + "3.0em" => '3.0em', + "3.05em" => '3.05em', + "3.1em" => '3.1em', + "3.15em" => '3.15em', + "3.2em" => '3.2em', + "3.25em" => '3.25em', + "3.3em" => '3.3em', + "3.35em" => '3.35em', + "3.4em" => '3.4em', + "3.45em" => '3.45em', + "3.5em" => '3.5em', + "3.55em" => '3.55em', + "3.6em" => '3.6em', + "3.65em" => '3.65em', + "3.7em" => '3.7em', + "3.75em" => '3.75em', + "3.8em" => '3.8em', + "3.85em" => '3.85em', + "3.9em" => '3.9em', + "3.95em" => '3.95em', + ); + + $form['top'] = array( + '#title' => t('Top'), + '#type' => 'select', + '#default_value' => isset($settings['top']) ? $settings['top'] : '', + '#options' => $options, + ); + + $form['right'] = array( + '#title' => t('Right'), + '#type' => 'select', + '#default_value' => isset($settings['right']) ? $settings['right'] : '', + '#options' => $options, + ); + + $form['bottom'] = array( + '#title' => t('Bottom'), + '#type' => 'select', + '#default_value' => isset($settings['bottom']) ? $settings['bottom'] : '', + '#options' => $options, + ); + + $form['left'] = array( + '#title' => t('Left'), + '#type' => 'select', + '#default_value' => isset($settings['left']) ? $settings['left'] : '', + '#options' => $options, + ); +} + +/** + * Copy padding selector information into the settings + */ +function ctools_stylizer_padding_selector_form_submit(&$form, &$form_state, &$values, &$settings) { + $settings = $values; +} + +function ctools_stylizer_padding_apply_style(&$stylesheet, $selector, $settings) { + $css = ''; + + if (isset($settings['top']) && $settings['top'] !== '') { + $css .= ' padding-top: ' . $settings['top'] . ";\n"; + } + + if (isset($settings['right']) && $settings['right'] !== '') { + $css .= ' padding-right: ' . $settings['right'] . ";\n"; + } + + if (isset($settings['bottom']) && $settings['bottom'] !== '') { + $css .= ' padding-bottom: ' . $settings['bottom'] . ";\n"; + } + + if (isset($settings['left']) && $settings['left'] !== '') { + $css .= ' padding-left: ' . $settings['left'] . ";\n"; + } + + if ($css) { + $stylesheet .= $selector . " {\n" . $css . "}\n"; + } + +} + +/** + * Check to see that a directory exists. + * + * This is an exact copy of core's, but without the stupid drupal_set_message + * because we need this to be silent. + * + * @todo this should probably be in another file. + */ +function ctools_file_check_directory(&$directory, $mode = 0, $form_item = NULL) { + $directory = rtrim($directory, '/\\'); + + // Check if directory exists. + if (!is_dir($directory)) { + if (($mode & FILE_CREATE_DIRECTORY) && @mkdir($directory)) { + @chmod($directory, 0775); // Necessary for non-webserver users. + } + else { + if ($form_item) { + form_set_error($form_item, t('The directory %directory does not exist.', array('%directory' => $directory))); + } + return FALSE; + } + } + + // Check to see if the directory is writable. + if (!is_writable($directory)) { + if (($mode & FILE_MODIFY_PERMISSIONS) && @chmod($directory, 0775)) { + drupal_set_message(t('The permissions of directory %directory have been changed to make it writable.', array('%directory' => $directory))); + } + else { + form_set_error($form_item, t('The directory %directory is not writable', array('%directory' => $directory))); + watchdog('file system', 'The directory %directory is not writable, because it does not have the correct permissions set.', array('%directory' => $directory), WATCHDOG_ERROR); + return FALSE; + } + } + + if ((file_directory_path() == $directory || file_directory_temp() == $directory) && !is_file("$directory/.htaccess")) { + $htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nOptions None\nOptions +FollowSymLinks"; + if (($fp = fopen("$directory/.htaccess", 'w')) && fputs($fp, $htaccess_lines)) { + fclose($fp); + chmod($directory .'/.htaccess', 0664); + } + else { + $variables = array('%directory' => $directory, '!htaccess' => '<br />'. nl2br(check_plain($htaccess_lines))); + form_set_error($form_item, t("Security warning: Couldn't write .htaccess file. Please create a .htaccess file in your %directory directory which contains the following lines: <code>!htaccess</code>", $variables)); + watchdog('security', "Security warning: Couldn't write .htaccess file. Please create a .htaccess file in your %directory directory which contains the following lines: <code>!htaccess</code>", $variables, WATCHDOG_ERROR); + } + } + + return TRUE; +} + +/** + * Blend two hex colors and return the GD color. + */ +function ctools_color_blend($img, $hex1, $hex2, $alpha) { + $in1 = ctools_color_unpack($hex1); + $in2 = ctools_color_unpack($hex2); + $out = array($img); + for ($i = 0; $i < 3; ++$i) { + $out[] = $in1[$i] + ($in2[$i] - $in1[$i]) * $alpha; + } + return call_user_func_array('imagecolorallocate', $out); +} + +/** + * Convert a hex color into an RGB triplet. + */ +function ctools_color_unpack($hex, $normalize = false) { + if (strlen($hex) == 4) { + $hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3]; + } + $c = hexdec($hex); + for ($i = 16; $i >= 0; $i -= 8) { + $out[] = (($c >> $i) & 0xFF) / ($normalize ? 255 : 1); + } + return $out; +} + +/** + * Convert a hex triplet into a GD color. + */ +function ctools_color_gd($img, $hex) { + $c = array_merge(array($img), ctools_color_unpack($hex)); + return call_user_func_array('imagecolorallocate', $c); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/stylizer.theme.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/stylizer.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..93b6275cc935ba8c70d4caf7197a07e11ad1d639 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/stylizer.theme.inc @@ -0,0 +1,48 @@ +<?php + +/** + * @file + * Contains theme registry and theme implementations for the content types. + */ + +/** + * Implementation of hook_theme to load all content plugins and pass thru if + * necessary. + */ +function ctools_stylizer_theme(&$theme) { + $theme['ctools_stylizer_color_scheme_form'] = array( + 'arguments' => array('form' => NULL), + 'file' => 'includes/stylizer.inc', + ); + + $theme['ctools_stylizer_preview_form'] = array( + 'arguments' => array('form' => NULL), + 'file' => 'includes/stylizer.inc', + ); + + $theme['ctools_style_icon'] = array( + 'arguments' => array('image' => NULL, 'title' => NULL), + 'file' => 'includes/stylizer.inc', + ); + + ctools_include('stylizer'); + // Register all themes given for basetypes. + $plugins = ctools_get_style_bases(); + $base_types = ctools_get_style_base_types(); + foreach ($plugins as $plugin) { + if (!empty($base_types[$plugin['module']][$plugin['type']]) && !empty($plugin['theme'])) { + $base_type = $base_types[$plugin['module']][$plugin['type']]; + $theme[$plugin['theme']] = array( + 'arguments' => $base_type['theme arguments'], + 'path' => $plugin['path'], + ); + + // if no theme function exists, assume template. + if (!function_exists("theme_$plugin[theme]")) { + $theme[$plugin['theme']]['template'] = str_replace('_', '-', $plugin['theme']); + $theme[$plugin['theme']]['file'] = $plugin['file']; // for preprocess. + } + } + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/utility.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/utility.inc new file mode 100644 index 0000000000000000000000000000000000000000..ef707a061b16123a0bebabf11b63a005227deddd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/utility.inc @@ -0,0 +1,77 @@ +<?php + +/** + * @file + * Contains general utility functions for CTools that do not need to be + * in the module file. + * + * In particular, things that are only needed during hook_menu() and + * hook_theme() are placed here. + */ + +/** + * Provide a hook passthrough to included files. + * + * To organize things neatly, each CTools tool gets its own toolname.$type.inc + * file. If it exists, it's loaded and ctools_$tool_$type() is executed. + * To save time we pass the $items array in so we don't need to do array + * addition. It modifies the array by reference and doesn't need to return it. + */ +function ctools_passthrough($module, $type, &$items) { + $files = drupal_system_listing('.' . $type . '.inc$', drupal_get_path('module', $module) . '/includes', 'name', 0); + foreach ($files as $file) { + require_once './' . $file->filename; + list($tool) = explode('.', $file->name, 2); + + $function = $module . '_' . str_replace ('-', '_', $tool) . '_' . $type; + if (function_exists($function)) { + $function($items); + } + } +} + +/** + * Implementation of hook_theme_registry_alter() + */ +function ctools_theme_registry_alter(&$registry) { + if ($registry['menu_local_tasks']['function'] == 'theme_menu_local_tasks') { + $registry['menu_local_tasks'] = array( + 'function' => 'ctools_theme_menu_local_tasks', + 'path' => drupal_get_path('module', 'ctools') . '/includes', + 'file' => 'menu.inc', + ) + $registry['menu_local_tasks']; + } + + if (isset($registry['help']['function']) && $registry['help']['function'] == 'theme_help') { + $registry['help'] = array( + 'function' => 'ctools_menu_help', + 'path' => drupal_get_path('module', 'ctools') . '/includes', + 'file' => 'menu.inc', + ) + $registry['help']; + } + + // Handle a special override for garland because it's cute and does its own + // thing with tabs and we can't ask users to edit a core theme for us. + if ($registry['menu_local_tasks']['function'] == 'phptemplate_menu_local_tasks' && + $registry['menu_local_tasks']['theme paths'][1] == 'themes/garland') { + $registry['menu_local_tasks'] = array( + 'function' => 'ctools_garland_menu_local_tasks', + 'path' => drupal_get_path('module', 'ctools') . '/includes', + 'file' => 'menu.inc', + ) + $registry['menu_local_tasks']; + } + + if (isset($registry['page']['preprocess functions'][2]) && + $registry['page']['preprocess functions'][2] == 'phptemplate_preprocess_page' && + $registry['page']['theme paths'][1] == 'themes/garland') { + $registry['page']['preprocess functions'][2] = 'ctools_garland_preprocess_page'; + } + + // Move this one last last last so it can catch changes made by modules and themes. + $key = array_search('ctools_preprocess_page', $registry['page']['preprocess functions']); + if ($key) { + unset($registry['page']['preprocess functions'][$key]); + } + $registry['page']['preprocess functions'][] = 'ctools_preprocess_page'; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/wizard.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/wizard.inc new file mode 100755 index 0000000000000000000000000000000000000000..c7299449cefe4e34adbac86ed0b440234440853a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/wizard.inc @@ -0,0 +1,462 @@ +<?php + +/** + * @file + * CTools' multi-step form wizard tool. + * + * This tool enables the creation of multi-step forms that go from one + * form to another. The forms themselves can allow branching if they + * like, and there are a number of configurable options to how + * the wizard operates. + * + * The wizard can also be friendly to ajax forms, such as when used + * with the modal tool. + * + * The wizard provides callbacks throughout the process, allowing the + * owner to control the flow. The general flow of what happens is: + * + * Generate a form + * submit a form + * based upon button clicked, 'finished', 'next form', 'cancel' or 'return'. + * + * Each action has its own callback, so cached objects can be modifed and or + * turned into real objects. Each callback can make decisions about where to + * go next if it wishes to override the default flow. + */ + +/** + * Display a multi-step form. + * + * Aside from the addition of the $form_info which contains an array of + * information and configuration so the multi-step wizard can do its thing, + * this function works a lot like ctools_build_form. + * + * Remember that the form builders for this form will receive + * &$form, &$form_state, NOT just &$form_state and no additional args. + * + * Do NOT use #required => TRUE with these forms as that validation + * cannot be skipped for the CANCEL button. + * + * @param $form_info + * An array of form info. @todo document the array. + * @param $step + * The current form step. + * @param &$form_state + * The form state array; this is a reference so the caller can get back + * whatever information the form(s) involved left for it. + */ +function ctools_wizard_multistep_form($form_info, $step, &$form_state) { + // allow order array to be optional + if (empty($form_info['order'])) { + foreach($form_info['forms'] as $step_id => $params) { + $form_info['order'][$step_id] = $params['title']; + } + } + + if (!isset($step)) { + $keys = array_keys($form_info['order']); + $step = array_shift($keys); + } + + ctools_wizard_defaults($form_info); + + $form_state['step'] = $step; + $form_state['form_info'] = $form_info; + + // Ensure we have form information for the current step. + if (!isset($form_info['forms'][$step])) { + return; + } + + // Ensure that whatever include file(s) were requested by the form info are + // actually included. + $info = $form_info['forms'][$step]; + + if (!empty($info['include'])) { + if (is_array($info['include'])) { + foreach ($info['include'] as $file) { + require_once './' . $file; + } + } + else { + require_once './' . $info['include']; + } + } + + // This tells ctools_build_form to apply our wrapper to the form. It + // will give it buttons and the like. + $form_state['wrapper callback'] = 'ctools_wizard_wrapper'; + if (!isset($form_state['rerender'])) { + $form_state['rerender'] = FALSE; + } + + $form_state['no_redirect'] = TRUE; + + ctools_include('form'); + $output = ctools_build_form($info['form id'], $form_state); + + if (empty($form_state['executed']) || !empty($form_state['rerender'])) { + if (empty($form_state['title']) && !empty($info['title'])) { + $form_state['title'] = $info['title']; + } + + if (!empty($form_state['ajax render'])) { + // Any include files should already be included by this point: + return $form_state['ajax render']($form_state, $output); + } + + // Automatically use the modal tool if set to true. + if (!empty($form_state['modal']) && empty($form_state['modal return'])) { + ctools_include('modal'); + + // This overwrites any previous commands. + $form_state['commands'] = ctools_modal_form_render($form_state, $output); + } + } + + if (!empty($form_state['executed'])) { + // We use the plugins get_function format because it's powerful and + // not limited to just functions. + ctools_include('plugins'); + + if (isset($form_state['clicked_button']['#wizard type'])) { + $type = $form_state['clicked_button']['#wizard type']; + // If we have a callback depending upon the type of button that was + // clicked, call it. + if ($function = ctools_plugin_get_function($form_info, "$type callback")) { + $function($form_state); + } + + // If the modal is in use, some special code for it: + if (!empty($form_state['modal']) && empty($form_state['modal return'])) { + if ($type != 'next') { + // Automatically dismiss the modal if we're not going to another form. + ctools_include('modal'); + $form_state['commands'][] = ctools_modal_command_dismiss(); + } + } + } + + if (empty($form_state['ajax'])) { + // redirect, if one is set. + if ($form_state['redirect']) { + return drupal_redirect_form(array(), $form_state['redirect']); + } + } + else if (isset($form_state['ajax next'])) { + // Clear a few items off the form state so we don't double post: + $next = $form_state['ajax next']; + unset($form_state['ajax next']); + unset($form_state['executed']); + unset($form_state['post']); + unset($form_state['next']); + return ctools_wizard_multistep_form($form_info, $next, $form_state); + } + + // If the callbacks wanted to do something besides go to the next form, + // it needs to have set $form_state['commands'] with something that can + // be rendered. + } + + // Render ajax commands if we have any. + if (isset($form_state['ajax']) && !empty($form_state['commands'])) { + return ctools_ajax_render($form_state['commands']); + } + + // Otherwise, return the output. + return $output; +} + +/** + * Provide a wrapper around another form for adding multi-step information. + */ +function ctools_wizard_wrapper(&$form, &$form_state) { + $form_info = &$form_state['form_info']; + $info = $form_info['forms'][$form_state['step']]; + + // Determine the next form from this step. + // Create a form trail if we're supposed to have one. + $trail = array(); + $previous = TRUE; + foreach ($form_info['order'] as $id => $title) { + if ($id == $form_state['step']) { + $previous = FALSE; + $class = 'wizard-trail-current'; + } + elseif ($previous) { + $not_first = TRUE; + $class = 'wizard-trail-previous'; + $form_state['previous'] = $id; + } + else { + $class = 'wizard-trail-next'; + if (!isset($form_state['next'])) { + $form_state['next'] = $id; + } + if (empty($form_info['show trail'])) { + break; + } + } + + if (!empty($form_info['show trail'])) { + if (!empty($form_info['free trail'])) { + // ctools_wizard_get_path() returns results suitable for #redirect + // which can only be directly used in drupal_goto. We have to futz + // with it. + $path = ctools_wizard_get_path($form_info, $id); + $options = array(); + if (!empty($path[1])) { + $options['query'] = $path[1]; + } + if (!empty($path[2])) { + $options['fragment'] = $path[2]; + } + $title = l($title, $path[0], $options); + } + $trail[$id] = '<span class="' . $class . '">' . $title . '</span>'; + } + } + + // Allow other modules to alter the trail. + drupal_alter('ctools_wizard_trail', $trail, $form_info); + + // Display the trail if instructed to do so. + if (!empty($form_info['show trail'])) { + ctools_add_css('wizard'); + $form['ctools_trail'] = array( + '#value' => theme(array('ctools_wizard_trail__' . $form_info['id'], 'ctools_wizard_trail'), $trail), + '#weight' => -1000, + ); + } + + if (empty($form_info['no buttons'])) { + // Ensure buttons stay on the bottom. + $form['buttons'] = array( + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + '#weight' => 1000, + ); + + $button_attributes = array(); + if (!empty($form_state['ajax']) && empty($form_state['modal'])) { + $button_attributes = array('class' => 'ctools-use-ajax'); + } + + if (!empty($form_info['show back']) && isset($form_state['previous'])) { + $form['buttons']['previous'] = array( + '#type' => 'submit', + '#value' => $form_info['back text'], + '#next' => $form_state['previous'], + '#wizard type' => 'next', + '#weight' => -2000, + '#skip validation' => TRUE, + // hardcode the submit so that it doesn't try to save data. + '#submit' => array('ctools_wizard_submit'), + '#attributes' => $button_attributes, + ); + + if (isset($form_info['no back validate']) || isset($info['no back validate'])) { + $form['buttons']['previous']['#validate'] = array(); + } + } + + // If there is a next form, place the next button. + if (isset($form_state['next']) || !empty($form_info['free trail'])) { + $form['buttons']['next'] = array( + '#type' => 'submit', + '#value' => $form_info['next text'], + '#next' => !empty($form_info['free trail']) ? $form_state['step'] : $form_state['next'], + '#wizard type' => 'next', + '#weight' => -1000, + '#attributes' => $button_attributes, + ); + } + + // There are two ways the return button can appear. If this is not the + // end of the form list (i.e, there is a next) then it's "update and return" + // to be clear. If this is the end of the path and there is no next, we + // call it 'Finish'. + + // Even if there is no direct return path (some forms may not want you + // leaving in the middle) the final button is always a Finish and it does + // whatever the return action is. + if (!empty($form_info['show return']) && !empty($form_state['next'])) { + $form['buttons']['return'] = array( + '#type' => 'submit', + '#value' => $form_info['return text'], + '#wizard type' => 'return', + '#attributes' => $button_attributes, + ); + } + else if (empty($form_state['next']) || !empty($form_info['free trail'])) { + $form['buttons']['return'] = array( + '#type' => 'submit', + '#value' => $form_info['finish text'], + '#wizard type' => 'finish', + '#attributes' => $button_attributes, + ); + } + + // If we are allowed to cancel, place a cancel button. + if ((isset($form_info['cancel path']) && !isset($form_info['show cancel'])) || !empty($form_info['show cancel'])) { + $form['buttons']['cancel'] = array( + '#type' => 'submit', + '#value' => $form_info['cancel text'], + '#wizard type' => 'cancel', + // hardcode the submit so that it doesn't try to save data. + '#skip validation' => TRUE, + '#submit' => array('ctools_wizard_submit'), + '#attributes' => $button_attributes, + ); + } + + // Set up optional validate handlers. + $form['#validate'] = array(); + if (function_exists($info['form id'] . '_validate')) { + $form['#validate'][] = $info['form id'] . '_validate'; + } + if (isset($info['validate']) && function_exists($info['validate'])) { + $form['#validate'][] = $info['validate']; + } + + // Set up our submit handler after theirs. Since putting something here will + // skip Drupal's autodetect, we autodetect for it. + + // We make sure ours is after theirs so that they get to change #next if + // the want to. + $form['#submit'] = array(); + if (function_exists($info['form id'] . '_submit')) { + $form['#submit'][] = $info['form id'] . '_submit'; + } + if (isset($info['submit']) && function_exists($info['submit'])) { + $form['#submit'][] = $info['submit']; + } + $form['#submit'][] = 'ctools_wizard_submit'; + } + + if (!empty($form_state['ajax'])) { + $params = ctools_wizard_get_path($form_state['form_info'], $form_state['step']); + if (count($params) > 1) { + $url = array_shift($params); + $options = array(); + + $keys = array(0 => 'query', 1 => 'fragment'); + foreach ($params as $key => $value) { + if (isset($keys[$key]) && isset($value)) { + $options[$keys[$key]] = $value; + } + } + + $params = array($url, $options); + } + $form['#action'] = call_user_func_array('url', $params); + } + + if (isset($info['wrapper']) && function_exists($info['wrapper'])) { + $info['wrapper']($form, $form_state); + } + + if (isset($form_info['wrapper']) && function_exists($form_info['wrapper'])) { + $form_info['wrapper']($form, $form_state); + } +} + +/** + * On a submit, go to the next form. + */ +function ctools_wizard_submit(&$form, &$form_state) { + if (isset($form_state['clicked_button']['#wizard type'])) { + $type = $form_state['clicked_button']['#wizard type']; + + // if AJAX enabled, we proceed slightly differently here. + if (!empty($form_state['ajax'])) { + if ($type == 'next') { + $form_state['ajax next'] = $form_state['clicked_button']['#next']; + } + } + else { + if ($type == 'cancel' && isset($form_state['form_info']['cancel path'])) { + $form_state['redirect'] = $form_state['form_info']['cancel path']; + } + else if ($type == 'next') { + $form_state['redirect'] = ctools_wizard_get_path($form_state['form_info'], $form_state['clicked_button']['#next']); + } + else if (isset($form_state['form_info']['return path'])) { + $form_state['redirect'] = $form_state['form_info']['return path']; + } + else if ($type == 'finish' && isset($form_state['form_info']['cancel path'])) { + $form_state['redirect'] = $form_state['form_info']['cancel path']; + } + } + } +} + +/** + * Create a path from the form info and a given step. + */ +function ctools_wizard_get_path($form_info, $step) { + if (is_array($form_info['path'])) { + foreach ($form_info['path'] as $id => $part) { + $form_info['path'][$id] = str_replace('%step', $step, $form_info['path'][$id]); + } + return $form_info['path']; + } + else { + return array(str_replace('%step', $step, $form_info['path'])); + } +} + +/** + * Set default parameters and callbacks if none are given. + * Callbacks follows pattern: + * $form_info['id']_$hook + * $form_info['id']_$form_info['forms'][$step_key]_$hook + */ +function ctools_wizard_defaults(&$form_info) { + $hook = $form_info['id']; + $defaults = array( + 'show trail' => FALSE, + 'free trail' => FALSE, + 'show back' => FALSE, + 'show cancel' => FALSE, + 'show return' => FALSE, + 'next text' => t('Continue'), + 'back text' => t('Back'), + 'return text' => t('Update and return'), + 'finish text' => t('Finish'), + 'cancel text' => t('Cancel'), + ); + + if (!empty($form_info['free trail'])) { + $defaults['next text'] = t('Update'); + $defaults['finish text'] = t('Save'); + } + + $form_info = $form_info + $defaults; + // set form callbacks if they aren't defined + foreach($form_info['forms'] as $step => $params) { + if (!$params['form id']) { + $form_callback = $hook . '_' . $step . '_form'; + $form_info['forms'][$step]['form id'] = $form_callback; + } + } + + // set button callbacks + $callbacks = array( + 'back callback' => '_back', + 'next callback' => '_next', + 'return callback' => '_return', + 'cancel callback' => '_cancel', + 'finish callback' => '_finish', + ); + + foreach($callbacks as $key => $callback) { + // never overwrite if explicity defined + if (empty($form_info[$key])) { + $wizard_callback = $hook . $callback; + if (function_exists($wizard_callback)) { + $form_info[$key] = $wizard_callback; + } + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/includes/wizard.theme.inc b/drupal/sites/default/boinc/modules/contrib/ctools/includes/wizard.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..acbccdfe1e63fc0e74c8c57b2f5194213f383c3a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/includes/wizard.theme.inc @@ -0,0 +1,24 @@ +<?php + +/** + * @file + * Themable for the wizard tool. + */ + +function ctools_wizard_theme(&$theme) { + $theme['ctools_wizard_trail'] = array( + 'arguments' => array('trail'), + 'file' => 'includes/wizard.theme.inc', + ); +} + +/** + * Themable display of the 'breadcrumb' trail to show the order of the + * forms. + */ +function theme_ctools_wizard_trail($trail) { + if (!empty($trail)) { + return '<div class="wizard-trail">' . implode(' » ', $trail) . '</div>'; + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/js/ajax-responder.js b/drupal/sites/default/boinc/modules/contrib/ctools/js/ajax-responder.js new file mode 100644 index 0000000000000000000000000000000000000000..530acc3a7ced8f1b4fdae0f2d8879245a4fe6b70 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/js/ajax-responder.js @@ -0,0 +1,702 @@ +/** + * @file + * + * CTools flexible AJAX responder object. + */ + +(function ($) { + Drupal.CTools = Drupal.CTools || {}; + Drupal.CTools.AJAX = Drupal.CTools.AJAX || {}; + Drupal.CTools.AJAX.commands = Drupal.CTools.AJAX.commands || {}; + Drupal.CTools.AJAX.commandCache = Drupal.CTools.AJAX.commandCache || {}; + Drupal.CTools.AJAX.scripts = {}; + Drupal.CTools.AJAX.css = {}; + Drupal.settings.CToolsUrlIsAjaxTrusted = Drupal.settings.CToolsUrlIsAjaxTrusted || {}; + + /** + * Success callback for an ajax request. + * + * This function expects to receive a packet of data from a JSON object + * which is essentially a list of commands. Each commands must have a + * 'command' setting and this setting must resolve to a function in the + * Drupal.CTools.AJAX.commands space. + */ + Drupal.CTools.AJAX.respond = function(data) { + var i; + for (i in data) { + if (data[i]['command'] && Drupal.CTools.AJAX.commands[data[i]['command']]) { + Drupal.CTools.AJAX.commands[data[i]['command']](data[i]); + } + } + }; + + /** + * Grab the response from the server and store it. + */ + Drupal.CTools.AJAX.warmCache = function () { + // Store this expression for a minor speed improvement. + var $this = $(this), + old_url = $this.attr('href'); + // If we are currently fetching, or if we have fetched this already which is + // ideal for things like pagers, where the previous page might already have + // been seen in the cache. + if ($this.hasClass('ctools-fetching') || !Drupal.CTools.AJAX.urlIsLocal(old_url) || Drupal.CTools.AJAX.commandCache[old_url]) { + return false; + } + + // Grab all the links that match this url and add the fetching class. + // This allows the caching system to grab each url once and only once + // instead of grabbing the url once per <a>. + var $objects = $('a[href="' + old_url + '"]'); + $objects.addClass('ctools-fetching'); + try { + var url = Drupal.CTools.AJAX.urlReplaceNojs(url); + var ajaxOptions = { + type: "POST", + url: url, + data: { 'js': 1, 'ctools_ajax': 1}, + global: true, + success: function (data) { + if (!Drupal.CTools.AJAX.isAjaxResponseTrusted(ajaxOptions.cXhr, url)) { + return this.error(ajaxOptions.cXhr); + } + + Drupal.CTools.AJAX.commandCache[old_url] = data; + $objects.addClass('ctools-cache-warmed').trigger('ctools-cache-warm', [data]); + }, + beforeSend: Drupal.CTools.AJAX.beforeSend, + complete: function() { + $objects.removeClass('ctools-fetching'); + }, + dataType: 'json' + }; + $.ajax(ajaxOptions); + } + catch (err) { + $objects.removeClass('ctools-fetching'); + return false; + } + + return false; + }; + + /** + * Cachable click handler to fetch the commands out of the cache or from url. + */ + Drupal.CTools.AJAX.clickAJAXCacheLink = function () { + var $this = $(this); + if ($this.hasClass('ctools-fetching')) { + $this.bind('ctools-cache-warm', function (event, data) { + Drupal.CTools.AJAX.respond(data); + }); + return false; + } + else { + if ($this.hasClass('ctools-cache-warmed') && Drupal.CTools.AJAX.commandCache[$this.attr('href')]) { + Drupal.CTools.AJAX.respond(Drupal.CTools.AJAX.commandCache[$this.attr('href')]); + return false; + } + else { + return Drupal.CTools.AJAX.clickAJAXLink.apply(this); + } + } + }; + + /** + * Generic replacement click handler to open the modal with the destination + * specified by the href of the link. + */ + Drupal.CTools.AJAX.clickAJAXLink = function() { + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } + + var url = $(this).attr('href'); + if (!Drupal.CTools.AJAX.urlIsLocal(url)) { + return false; + } + $(this).addClass('ctools-ajaxing'); + try { + url = Drupal.CTools.AJAX.urlReplaceNojs(url); + $.ajax({ + type: "POST", + url: url, + data: { 'js': 1, 'ctools_ajax': 1}, + global: true, + success: Drupal.CTools.AJAX.success, + beforeSend: Drupal.CTools.AJAX.beforeSend, + error: function(xhr) { + Drupal.CTools.AJAX.handleErrors(xhr, url); + }, + complete: function() { + $('.ctools-ajaxing').removeClass('ctools-ajaxing'); + }, + dataType: 'json' + }); + } + catch (err) { + alert("An error occurred while attempting to process " + url); + $('.ctools-ajaxing').removeClass('ctools-ajaxing'); + return false; + } + + return false; + }; + + /** + * Generic replacement click handler to open the modal with the destination + * specified by the href of the link. + */ + Drupal.CTools.AJAX.clickAJAXButton = function() { + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } + + // Put our button in. + this.form.clk = this; + + var url = Drupal.CTools.AJAX.findURL(this); + $(this).addClass('ctools-ajaxing'); + try { + if (url) { + url = Drupal.CTools.AJAX.urlReplaceNojs(url); + $.ajax({ + type: "POST", + url: url, + data: { 'js': 1, 'ctools_ajax': 1}, + global: true, + success: Drupal.CTools.AJAX.success, + beforeSend: Drupal.CTools.AJAX.beforeSend, + error: function(xhr) { + Drupal.CTools.AJAX.handleErrors(xhr, url); + }, + complete: function() { + $('.ctools-ajaxing').removeClass('ctools-ajaxing'); + }, + dataType: 'json' + }); + } + else { + var form = this.form; + url = $(form).attr('action'); + setTimeout(function() { Drupal.CTools.AJAX.ajaxSubmit(form, url); }, 1); + } + } + catch (err) { + alert("An error occurred while attempting to process " + url); + $(this).removeClass('ctools-ajaxing'); + return false; + } + return false; + }; + + /** + * Helper method to stash the xhr object so it is available in the success callback. + */ + Drupal.CTools.AJAX.beforeSend = function(xhr) { + this.cXhr = xhr; + }; + + /** + * Respond wrapper that checks security of the request. + */ + Drupal.CTools.AJAX.success = function(data) { + if (data !== null && !Drupal.CTools.AJAX.isAjaxResponseTrusted(this.cXhr, this.url)) { + return this.error(this.cXhr); + } + Drupal.CTools.AJAX.respond(data); + }; + + Drupal.CTools.AJAX.isAjaxResponseTrusted = function(xhr, url) { + return Drupal.settings.CToolsUrlIsAjaxTrusted[url] || (Drupal.CTools.AJAX.urlIsLocal(url) && xhr.getResponseHeader('X-Drupal-Ajax-Token') === '1'); + }; + + /** + * Event handler to submit an AJAX form. + * + * Using a secondary event ensures that our form submission is last, which + * is needed when submitting wysiwyg controlled forms, for example. + */ + Drupal.CTools.AJAX.ajaxSubmit = function (form, url) { + var $form = $(form); + + if ($form.hasClass('ctools-ajaxing')) { + return false; + } + + $form.addClass('ctools-ajaxing'); + + try { + url = Drupal.CTools.AJAX.urlReplaceNojs(url); + + var ajaxOptions = { + type: 'POST', + url: url, + data: { 'js': 1, 'ctools_ajax': 1}, + global: true, + success: function(data) { + Drupal.CTools.AJAX.success.apply(ajaxOptions, [data]); + }, + beforeSend: function (xhr) { + Drupal.CTools.AJAX.beforeSend.apply(ajaxOptions, [xhr]); + }, + error: function(xhr) { + Drupal.CTools.AJAX.handleErrors(xhr, url); + }, + complete: function() { + $('.ctools-ajaxing').removeClass('ctools-ajaxing'); + $('div.ctools-ajaxing-temporary').remove(); + }, + dataType: 'json' + }; + + // If the form requires uploads, use an iframe instead and add data to + // the submit to support this and use the proper response. + if ($form.attr('enctype') == 'multipart/form-data') { + $form.append('<input type="hidden" name="ctools_multipart" value="1">'); + var ajaxIframeOptions = { + success: function(data) { + if (!Drupal.CTools.AJAX.isAjaxResponseTrusted(ajaxOptions.cXhr, url)) { + return this.error(ajaxOptions.cXhr); + } + + Drupal.CTools.AJAX.iFrameJsonRespond(data); + }, + iframe: true + }; + ajaxOptions = $.extend(ajaxOptions, ajaxIframeOptions); + } + + $form.ajaxSubmit(ajaxOptions); + } + catch (err) { + alert("An error occurred while attempting to process " + url); + $('.ctools-ajaxing').removeClass('ctools-ajaxing'); + $('div.ctools-ajaxing-temporary').remove(); + return false; + } + }; + + /** + * Wrapper for handling JSON responses from an iframe submission + */ + Drupal.CTools.AJAX.iFrameJsonRespond = function(data) { + var myJson = eval(data); + Drupal.CTools.AJAX.respond(myJson); + }; + + /** + * Display error in a more fashion way + */ + Drupal.CTools.AJAX.handleErrors = function(xhr, path) { + var error_text = ''; + + if ((xhr.status == 500 && xhr.responseText) || xhr.status == 200) { + error_text = xhr.responseText; + + // Replace all < and > by < and > + error_text = error_text.replace("/&(lt|gt);/g", function (m, p) { + return (p == "lt")? "<" : ">"; + }); + + // Now, replace all html tags by empty spaces + error_text = error_text.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,""); + + // Fix end lines + error_text = error_text.replace(/[\n]+\s+/g,"\n"); + } + else if (xhr.status == 500) { + error_text = xhr.status + ': ' + Drupal.t("Internal server error. Please see server or PHP logs for error information."); + } + else { + error_text = xhr.status + ': ' + xhr.statusText; + } + + alert(Drupal.t("An error occurred at @path.\n\nError Description: @error", {'@path': path, '@error': error_text})); + }; + + /** + * Generic replacement for change handler to execute ajax method. + */ + Drupal.CTools.AJAX.changeAJAX = function () { + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } + + var url = Drupal.CTools.AJAX.findURL(this); + $(this).addClass('ctools-ajaxing'); + var $object = $(this); + var form_id = $object.parents('form').get(0).id; + try { + if (url) { + url = Drupal.CTools.AJAX.urlReplaceNojs(url); + $.ajax({ + type: "POST", + url: url, + data: {'ctools_changed': $(this).val(), 'js': 1, 'ctools_ajax': 1 }, + global: true, + success: Drupal.CTools.AJAX.success, + beforeSend: Drupal.CTools.AJAX.beforeSend, + error: function(xhr) { + Drupal.CTools.AJAX.handleErrors(xhr, url); + }, + complete: function() { + $('.ctools-ajaxing').removeClass('ctools-ajaxing'); + if ($(object).hasClass('ctools-ajax-submit-onchange')) { + $('form#' + form_id).submit(); + } + }, + dataType: 'json' + }); + } + else { + if ($object.hasClass('ctools-ajax-submit-onchange')) { + $('form#' + form_id).submit(); + } + return false; + } + } + catch (err) { + alert("An error occurred while attempting to process " + url); + $('.ctools-ajaxing').removeClass('ctools-ajaxing'); + return false; + } + return false; + }; + + /** + * Find a URL for an AJAX button. + * + * The URL for this gadget will be composed of the values of items by + * taking the ID of this item and adding -url and looking for that + * class. They need to be in the form in order since we will + * concat them all together using '/'. + */ + Drupal.CTools.AJAX.findURL = function(item) { + var url = ''; + var url_class = '.' + $(item).attr('id') + '-url'; + $(url_class).each( + function() { + if (url && $(this).val()) { + url += '/'; + } + url += $(this).val(); + }); + return Drupal.CTools.AJAX.urlIsLocal(url) ? url : '/'; + }; + + Drupal.CTools.AJAX.getPath = function (link) { + if (!link) { + return; + } + + var index = link.indexOf('?'); + if (index != -1) { + link = link.substr(0, index); + } + + return link; + }; + + Drupal.CTools.AJAX.commands.prepend = function(data) { + $(data.selector).prepend(data.data); + Drupal.attachBehaviors($(data.selector)); + }; + + Drupal.CTools.AJAX.commands.append = function(data) { + $(data.selector).append(data.data); + Drupal.attachBehaviors($(data.selector)); + }; + + Drupal.CTools.AJAX.commands.replace = function(data) { + $(data.selector).replaceWith(data.data); + Drupal.attachBehaviors($(data.selector)); + }; + + Drupal.CTools.AJAX.commands.after = function(data) { + var object = $(data.data); + $(data.selector).after(object); + Drupal.attachBehaviors(object); + }; + + Drupal.CTools.AJAX.commands.before = function(data) { + var object = $(data.data); + $(data.selector).before(object); + Drupal.attachBehaviors(object); + }; + + Drupal.CTools.AJAX.commands.html = function(data) { + $(data.selector).html(data.data); + Drupal.attachBehaviors($(data.selector)); + }; + + Drupal.CTools.AJAX.commands.remove = function(data) { + $(data.selector).remove(); + }; + + Drupal.CTools.AJAX.commands.changed = function(data) { + if (!$(data.selector).hasClass('changed')) { + $(data.selector).addClass('changed'); + if (data.star) { + $(data.selector).find(data.star).append(' <span class="star">*</span> '); + } + } + }; + + Drupal.CTools.AJAX.commands.alert = function(data) { + alert(data.text, data.title); + }; + + Drupal.CTools.AJAX.commands.css = function(data) { + /* + if (data.selector && data.selector.contains('* html ')) { + // This indicates an IE hack and we should only do it if we are IE. + if (!jQuery.browser.msie) { + return; + } + data.selector = data.selector.replace('* html ', ''); + } + */ + $(data.selector).css(data.argument); + }; + + Drupal.CTools.AJAX.commands.css_files = function(data) { + // Build a list of css files already loaded: + $('link:not(.ctools-temporary-css)').each(function () { + if ($(this).attr('type') == 'text/css') { + var href = $(this).attr('href'); + var link = Drupal.CTools.AJAX.getPath(href); + if (link && Drupal.CTools.AJAX.urlIsLocal(href)) { + Drupal.CTools.AJAX.css[link] = href; + } + } + }); + + var html = ''; + for (var i = 0; i < data.argument.length; i++) { + var link = Drupal.CTools.AJAX.getPath(data.argument[i].file); + if (!Drupal.CTools.AJAX.css[link]) { + html += '<link class="ctools-temporary-css" type="text/css" rel="stylesheet" media="' + data.argument[i].media + + '" href="' + data.argument[i].file + '" />'; + } + } + + if (html) { + $('link.ctools-temporary-css').remove(); + $('body').append($(html)); + } + }; + + Drupal.CTools.AJAX.commands.settings = function(data) { + $.extend(Drupal.settings, data.argument); + }; + + Drupal.CTools.AJAX.commands.scripts = function(data) { + // Build a list of scripts already loaded: + $('script').each(function () { + var link = Drupal.CTools.AJAX.getPath($(this).attr('src')); + if (link) { + Drupal.CTools.AJAX.scripts[link] = $(this).attr('src'); + } + }); + + var html = '', + head = document.getElementsByTagName('head')[0]; + for (var i = 0; i < data.argument.length; i++) { + var link = Drupal.CTools.AJAX.getPath(data.argument[i]); + if (!Drupal.CTools.AJAX.scripts[link]) { + Drupal.CTools.AJAX.scripts[link] = link; + // Use this to actually get the script tag into the dom, which is + // needed for scripts that self-reference to determine paths. + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = data.argument[i]; + head.appendChild(script); + html += '<script type="text/javascript" src="' + data.argument[i] + '"></script>'; + } + } + + if (html) { + $('body').append($(html)); + } + }; + + Drupal.CTools.AJAX.commands.data = function(data) { + $(data.selector).data(data.name, data.value); + }; + + Drupal.CTools.AJAX.commands.attr = function(data) { + $(data.selector).attr(data.name, data.value); + }; + + Drupal.CTools.AJAX.commands.restripe = function(data) { + // :even and :odd are reversed because jquery counts from 0 and + // we count from 1, so we're out of sync. + $('tbody tr:not(:hidden)', $(data.selector)) + .removeClass('even') + .removeClass('odd') + .filter(':even') + .addClass('odd') + .end() + .filter(':odd') + .addClass('even'); + }; + + Drupal.CTools.AJAX.commands.redirect = function(data) { + if (data.delay > 0) { + setTimeout(function () { + if (data.new_window) { + window.open(data.url, '_blank'); + } + else { + location.href = data.url; + } + }, data.delay); + } + else if (data.new_window) { + window.open(data.url, '_blank'); + } + else { + location.href = data.url; + } + }; + + Drupal.CTools.AJAX.commands.reload = function(data) { + location.reload(); + }; + + Drupal.CTools.AJAX.commands.submit = function(data) { + $(data.selector).submit(); + }; + + /** + * Replacing 'nojs' with 'ajax' in the URL allows for an easy method to let + * the server detect when it needs to degrade gracefully. + * There are five scenarios to check for: + * 1. /nojs/ + * 2. /nojs$ - The end of a URL string. + * 3. /nojs? - Followed by a query (with clean URLs enabled). + * E.g.: path/nojs?destination=foobar + * 4. /nojs& - Followed by a query (without clean URLs enabled). + * E.g.: ?q=path/nojs&destination=foobar + * 5. /nojs# - Followed by a fragment. + * E.g.: path/nojs#myfragment + */ + Drupal.CTools.AJAX.urlReplaceNojs = function(url) { + var new_url = url.replace(/\/nojs(\/|$|\?|&|#)/g, '/ajax$1'); + + // If the 'nojs' version of the URL is trusted, also trust the 'ajax' + // version. + if (Drupal.settings.CToolsUrlIsAjaxTrusted[url]) { + Drupal.settings.CToolsUrlIsAjaxTrusted[new_url] = true; + } + return new_url; + }; + + /** + * Returns the passed in URL as an absolute URL. + * + * @param url + * The URL string to be normalized to an absolute URL. + * + * @return + * The normalized, absolute URL. + * + * @see https://github.com/angular/angular.js/blob/v1.4.4/src/ng/urlUtils.js + * @see https://grack.com/blog/2009/11/17/absolutizing-url-in-javascript + * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L53 + */ + Drupal.CTools.AJAX.absoluteUrl = function (url) { + var urlParsingNode = document.createElement('a'); + + // Decode the URL first; this is required by IE <= 6. Decoding non-UTF-8 + // strings may throw an exception. + try { + url = decodeURIComponent(url); + } catch (e) {} + + urlParsingNode.setAttribute('href', url); + + // IE <= 7 normalizes the URL when assigned to the anchor node similar to + // the other browsers. + return urlParsingNode.cloneNode(false).href; + }; + + /** + * Returns true if the URL is within Drupal's base path. + * + * @param url + * The URL string to be tested. + * + * @return + * Boolean true if local, or false if the url may be external or have a scheme. + * + * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L58 + */ + Drupal.CTools.AJAX.urlIsLocal = function (url) { + // Always use browser-derived absolute URLs in the comparison, to avoid + // attempts to break out of the base path using directory traversal. + var absoluteUrl = Drupal.CTools.AJAX.absoluteUrl(url); + + var protocol = location.protocol; + + // Consider URLs that match this site's base URL but use HTTPS instead of HTTP + // as local as well. + if (protocol === 'http:' && absoluteUrl.indexOf('https:') === 0) { + protocol = 'https:'; + } + var baseUrl = protocol + '//' + location.host + Drupal.settings.basePath.slice(0, -1); + + // Decoding non-UTF-8 strings may throw an exception. + try { + absoluteUrl = decodeURIComponent(absoluteUrl); + } catch (e) {} + try { + baseUrl = decodeURIComponent(baseUrl); + } catch (e) {} + + // The given URL matches the site's base URL, or has a path under the site's + // base URL. + return absoluteUrl === baseUrl || absoluteUrl.indexOf(baseUrl + '/') === 0; + }; + + /** + * Bind links that will open modals to the appropriate function. + */ + Drupal.behaviors.CToolsAJAX = function(context) { + // Bind links + + // Note that doing so in this order means that the two classes can be + // used together safely. + $('a.ctools-use-ajax-cache:not(.ctools-use-ajax-processed)', context) + .addClass('ctools-use-ajax-processed') + .click(Drupal.CTools.AJAX.clickAJAXCacheLink) + .each(function () { + Drupal.CTools.AJAX.warmCache.apply(this); + }); + + $('a.ctools-use-ajax:not(.ctools-use-ajax-processed)', context) + .addClass('ctools-use-ajax-processed') + .click(Drupal.CTools.AJAX.clickAJAXLink); + + + // Bind buttons + $('input.ctools-use-ajax:not(.ctools-use-ajax-processed), button.ctools-use-ajax:not(.ctools-use-ajax-processed)', context) + .addClass('ctools-use-ajax-processed') + .click(Drupal.CTools.AJAX.clickAJAXButton); + + // Bind select + $('select, input:text, input:radio, input:checkbox', context) + .filter('.ctools-use-ajax-onchange:not(.ctools-use-ajax-processed)') + .addClass('ctools-use-ajax-processed') + .change(Drupal.CTools.AJAX.changeAJAX); + + // Add information about loaded CSS and JS files. + if (Drupal.settings.CToolsAJAX && Drupal.settings.CToolsAJAX.css) { + $.extend(Drupal.CTools.AJAX.css, Drupal.settings.CToolsAJAX.css); + } + if (Drupal.settings.CToolsAJAX && Drupal.settings.CToolsAJAX.scripts) { + $.extend(Drupal.CTools.AJAX.scripts, Drupal.settings.CToolsAJAX.scripts); + } + }; +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/js/auto-submit.js b/drupal/sites/default/boinc/modules/contrib/ctools/js/auto-submit.js new file mode 100644 index 0000000000000000000000000000000000000000..40653398e1a5ea6c8275a275b3727a5a11dad8c9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/js/auto-submit.js @@ -0,0 +1,71 @@ + +/** + * To make a form auto submit, all you have to do is 3 things: + * + * ctools_add_js('auto-submit'); + * + * On gadgets you want to auto-submit when changed, add the ctools-auto-submit + * class. With FAPI, add: + * @code + * '#attributes' => array('class' => 'ctools-auto-submit'), + * @endcode + * + * If you want to have auto-submit for every form element, + * add the ctools-auto-submit-full-form to the form. With FAPI, add: + * @code + * '#attributes' => array('class' => 'ctools-auto-submit-full-form'), + * @endcode + * + * Finally, you have to identify which button you want clicked for autosubmit. + * The behavior of this button will be honored if it's ajaxy or not: + * @code + * '#attributes' => array('class' => 'ctools-use-ajax ctools-auto-submit-click'), + * @endcode + * + * Currently only 'select' and 'textfield' types are supported. We probably + * could use additional support for radios and checkboxes. + */ + +Drupal.behaviors.CToolsAutoSubmit = function() { + var timeoutID = 0; + + // Bind to any select widgets that will be auto submitted. + $('select.ctools-auto-submit:not(.ctools-auto-submit-processed),.ctools-auto-submit-full-form select:not(.ctools-auto-submit-processed)') + .addClass('.ctools-auto-submit-processed') + .change(function() { + $(this.form).find('.ctools-auto-submit-click').click(); + }); + + // Bind to any textfield widgets that will be auto submitted. + $('input[type=text].ctools-auto-submit:not(.ctools-auto-submit-processed),.ctools-auto-submit-full-form input[type=text]:not(.ctools-auto-submit-processed)') + .addClass('.ctools-auto-submit-processed') + .keyup(function(e) { + var form = this.form; + switch (e.keyCode) { + case 16: // shift + case 17: // ctrl + case 18: // alt + case 20: // caps lock + case 33: // page up + case 34: // page down + case 35: // end + case 36: // home + case 37: // left arrow + case 38: // up arrow + case 39: // right arrow + case 40: // down arrow + case 9: // tab + case 13: // enter + case 27: // esc + return false; + default: + if (!$(form).hasClass('ctools-ajaxing')) { + if ((timeoutID)) { + clearTimeout(timeoutID); + } + + timeoutID = setTimeout(function() { $(form).find('.ctools-auto-submit-click').click(); }, 300); + } + } + }); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/js/collapsible-div.js b/drupal/sites/default/boinc/modules/contrib/ctools/js/collapsible-div.js new file mode 100644 index 0000000000000000000000000000000000000000..4205978760dba6e7fdb19879c030463eb8b99479 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/js/collapsible-div.js @@ -0,0 +1,238 @@ +/** + * @file + * Javascript required for a simple collapsible div. + * + * Creating a collapsible div with this doesn't take too much. There are + * three classes necessary: + * + * - ctools-collapsible-container: This is the overall container that will be + * collapsible. This must be a div. + * - ctools-collapsible-handle: This is the title area, and is what will be + * visible when it is collapsed. This can be any block element, such as div + * or h2. + * - ctools-collapsible-content: This is the ocntent area and will only be + * visible when expanded. This must be a div. + * + * Adding 'ctools-collapsible-remember' to the container class will cause the + * state of the container to be stored in a cookie, and remembered from page + * load to page load. This will only work if the container has a unique ID, so + * very carefully add IDs to your containers. + * + * If the class 'ctools-no-container' is placed on the container, the container + * will be the handle. The content will be found by appending '-content' to the + * id of the handle. The ctools-collapsible-handle and + * ctools-collapsible-content classes will not be required in that case, and no + * restrictions on what of data the container is are placed. Like + * ctools-collapsible-remember this requires an id to eist. + * + * The content will be 'open' unless the container class has 'ctools-collapsed' + * as a class, which will cause the container to draw collapsed. + */ + +(function ($) { + // All CTools tools begin with this if they need to use the CTools namespace. + if (!Drupal.CTools) { + Drupal.CTools = {}; + } + + /** + * Object to store state. + * + * This object will remember the state of collapsible containers. The first + * time a state is requested, it will check the cookie and set up the variable. + * If a state has been changed, when the window is unloaded the state will be + * saved. + */ + Drupal.CTools.Collapsible = { + state: {}, + stateLoaded: false, + stateChanged: false, + cookieString: 'ctools-collapsible-state=', + + /** + * Get the current collapsed state of a container. + * + * If set to 1, the container is open. If set to -1, the container is + * collapsed. If unset the state is unknown, and the default state should + * be used. + */ + getState: function (id) { + if (!this.stateLoaded) { + this.loadCookie(); + } + + return this.state[id]; + }, + + /** + * Set the collapsed state of a container for subsequent page loads. + * + * Set the state to 1 for open, -1 for collapsed. + */ + setState: function (id, state) { + if (!this.stateLoaded) { + this.loadCookie(); + } + + this.state[id] = state; + + if (!this.stateChanged) { + this.stateChanged = true; + $(window).unload(this.unload); + } + }, + + /** + * Check the cookie and load the state variable. + */ + loadCookie: function () { + // If there is a previous instance of this cookie + if (document.cookie.length > 0) { + // Get the number of characters that have the list of values + // from our string index. + offset = document.cookie.indexOf(this.cookieString); + + // If its positive, there is a list! + if (offset != -1) { + offset += this.cookieString.length; + var end = document.cookie.indexOf(';', offset); + if (end == -1) { + end = document.cookie.length; + } + + // Get a list of all values that are saved on our string + var cookie = unescape(document.cookie.substring(offset, end)); + + if (cookie != '') { + var cookieList = cookie.split(','); + for (var i = 0; i < cookieList.length; i++) { + var info = cookieList[i].split(':'); + this.state[info[0]] = info[1]; + } + } + } + } + + this.stateLoaded = true; + }, + + /** + * Turn the state variable into a string and store it in the cookie. + */ + storeCookie: function () { + var cookie = ''; + + // Get a list of IDs, saparated by comma + for (i in this.state) { + if (cookie != '') { + cookie += ','; + } + cookie += i + ':' + this.state[i]; + } + + // Save this values on the cookie + document.cookie = this.cookieString + escape(cookie) + ';path=/'; + }, + + /** + * Respond to the unload event by storing the current state. + */ + unload: function() { + Drupal.CTools.Collapsible.storeCookie(); + } + }; + + // Set up an array for callbacks. + Drupal.CTools.CollapsibleCallbacks = []; + Drupal.CTools.CollapsibleCallbacksAfterToggle = []; + + /** + * Bind collapsible behavior to a given container. + */ + Drupal.CTools.bindCollapsible = function () { + var $container = $(this); + + // Allow the specification of the 'no container' class, which means the + // handle and the container can be completely independent. + if ($container.hasClass('ctools-no-container') && $container.attr('id')) { + // In this case, the container *is* the handle and the content is found + // by adding '-content' to the id. Obviously, an id is required. + var handle = $container; + var content = $('#' + $container.attr('id') + '-content'); + } + else { + var handle = $container.children('.ctools-collapsible-handle'); + var content = $container.children('div.ctools-collapsible-content'); + } + + if (content.length) { + // Create the toggle item and place it in front of the toggle. + var toggle = $('<span class="ctools-toggle"></span>'); + handle.before(toggle); + + // If the remember class is set, check to see if we have a remembered + // state stored. + if ($container.hasClass('ctools-collapsible-remember') && $container.attr('id')) { + var state = Drupal.CTools.Collapsible.getState($container.attr('id')); + if (state == 1) { + $container.removeClass('ctools-collapsed'); + } + else if (state == -1) { + $container.addClass('ctools-collapsed'); + } + } + + // If we should start collapsed, do so: + if ($container.hasClass('ctools-collapsed')) { + toggle.toggleClass('ctools-toggle-collapsed'); + content.hide(); + } + + var afterToggle = function () { + if (Drupal.CTools.CollapsibleCallbacksAfterToggle) { + for (i in Drupal.CTools.CollapsibleCallbacksAfterToggle) { + Drupal.CTools.CollapsibleCallbacksAfterToggle[i]($container, handle, content, toggle); + } + } + } + + var clickMe = function () { + if (Drupal.CTools.CollapsibleCallbacks) { + for (i in Drupal.CTools.CollapsibleCallbacks) { + Drupal.CTools.CollapsibleCallbacks[i]($container, handle, content, toggle); + } + } + + // If the container is a table element slideToggle does not do what + // we want, so use toggle() instead. + if ($container.is('table')) { + content.toggle(0, afterToggle); + } + else { + content.slideToggle(100, afterToggle); + } + + toggle.toggleClass('ctools-toggle-collapsed'); + + // If we're supposed to remember the state of this class, do so. + if ($container.hasClass('ctools-collapsible-remember') && $container.attr('id')) { + var state = toggle.hasClass('ctools-toggle-collapsed') ? -1 : 1; + Drupal.CTools.Collapsible.setState($container.attr('id'), state); + } + } + + // Let both the toggle and the handle be clickable. + toggle.click(clickMe); + handle.click(clickMe); + } + }; + + /** + * Support Drupal's 'behaviors' system for binding. + */ + Drupal.behaviors.CToolsCollapsible = function(context) { + $('.ctools-collapsible-container:not(.ctools-collapsible-processed)', context) + .each(Drupal.CTools.bindCollapsible) + .addClass('ctools-collapsible-processed'); + } +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/js/dependent.js b/drupal/sites/default/boinc/modules/contrib/ctools/js/dependent.js new file mode 100644 index 0000000000000000000000000000000000000000..10add7a4196b4553e39c5092026a6e6539bab0d6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/js/dependent.js @@ -0,0 +1,200 @@ +/** + * @file + * + * Written by dmitrig01 (Dmitri Gaskin) for CTools; this provides dependent + * visibility for form items in CTools' ajax forms. + * + * To your $form item definition add: + * - '#process' => array('CTools_process_dependency'), + * - Add '#dependency' => array('id-of-form-item' => array(list, of, values, that, + make, this, item, show), + * + * Special considerations: + * - radios are harder. Because Drupal doesn't give radio groups individual ids, + * use 'radio:name-of-radio' + * + * - Checkboxes don't have their own id, so you need to add one in a div + * around the checkboxes via #prefix and #suffix. You actually need to add TWO + * divs because it's the parent that gets hidden. Also be sure to retain the + * 'expand_checkboxes' in the #process array, because the CTools process will + * override it. + */ + +(function ($) { + Drupal.CTools = Drupal.CTools || {}; + Drupal.CTools.dependent = {}; + + Drupal.CTools.dependent.bindings = {}; + Drupal.CTools.dependent.activeBindings = {}; + Drupal.CTools.dependent.activeTriggers = []; + + Drupal.CTools.dependent.inArray = function(array, search_term) { + var i = array.length; + while (i--) { + if (array[i] == search_term) { + return true; + } + } + return false; + } + + + Drupal.CTools.dependent.autoAttach = function() { + // Clear active bindings and triggers. + for (i in Drupal.CTools.dependent.activeTriggers) { + jQuery(Drupal.CTools.dependent.activeTriggers[i]).unbind('change'); + } + Drupal.CTools.dependent.activeTriggers = []; + Drupal.CTools.dependent.activeBindings = {}; + Drupal.CTools.dependent.bindings = {}; + + if (!Drupal.settings.CTools) { + return; + } + + // Iterate through all relationships + for (id in Drupal.settings.CTools.dependent) { + + // Drupal.CTools.dependent.activeBindings[id] is a boolean, + // whether the binding is active or not. Defaults to no. + Drupal.CTools.dependent.activeBindings[id] = 0; + // Iterate through all possible values + for(bind_id in Drupal.settings.CTools.dependent[id].values) { + // This creates a backward relationship. The bind_id is the ID + // of the element which needs to change in order for the id to hide or become shown. + // The id is the ID of the item which will be conditionally hidden or shown. + // Here we're setting the bindings for the bind + // id to be an empty array if it doesn't already have bindings to it + if (!Drupal.CTools.dependent.bindings[bind_id]) { + Drupal.CTools.dependent.bindings[bind_id] = []; + } + // Add this ID + Drupal.CTools.dependent.bindings[bind_id].push(id); + // Big long if statement. + // Drupal.settings.CTools.dependent[id].values[bind_id] holds the possible values + + if (bind_id.substring(0, 6) == 'radio:') { + var trigger_id = "input[name='" + bind_id.substring(6) + "']"; + } + else { + var trigger_id = '#' + bind_id; + } + + Drupal.CTools.dependent.activeTriggers.push(trigger_id); + + + var getValue = function(item, trigger) { + if (item.substring(0, 6) == 'radio:') { + var val = jQuery(trigger + ':checked').val(); + } + else { + switch (jQuery(trigger).attr('type')) { + case 'checkbox': + var val = jQuery(trigger).attr('checked') || 0; + break; + default: + var val = jQuery(trigger).val(); + } + } + return val; + } + + var setChangeTrigger = function(trigger_id, bind_id) { + // Triggered when change() is clicked. + var changeTrigger = function() { + var val = getValue(bind_id, trigger_id); + + for (i in Drupal.CTools.dependent.bindings[bind_id]) { + var id = Drupal.CTools.dependent.bindings[bind_id][i]; + + // Fix numerous errors + if (typeof id != 'string') { + continue; + } + + // This bit had to be rewritten a bit because two properties on the + // same set caused the counter to go up and up and up. + if (!Drupal.CTools.dependent.activeBindings[id]) { + Drupal.CTools.dependent.activeBindings[id] = {}; + } + + if (Drupal.CTools.dependent.inArray(Drupal.settings.CTools.dependent[id].values[bind_id], val)) { + Drupal.CTools.dependent.activeBindings[id][bind_id] = 'bind'; + } + else { + delete Drupal.CTools.dependent.activeBindings[id][bind_id]; + } + + var len = 0; + for (i in Drupal.CTools.dependent.activeBindings[id]) { + len++; + } + + var object = jQuery('#' + id + '-wrapper'); + if (!object.size()) { + object = jQuery('#' + id).parent(); + } + + if (Drupal.settings.CTools.dependent[id].type == 'disable') { + if (Drupal.settings.CTools.dependent[id].num <= len) { + // Show if the element if criteria is matched + object.attr('disabled', false); + object.children().attr('disabled', false); + } + else { + // Otherwise hide. Use css rather than hide() because hide() + // does not work if the item is already hidden, for example, + // in a collapsed fieldset. + object.attr('disabled', true); + object.children().attr('disabled', true); + } + } + else { + if (Drupal.settings.CTools.dependent[id].num <= len) { + // Show if the element if criteria is matched + object.show(0); + object.addClass('dependent-options'); + } + else { + // Otherwise hide. Use css rather than hide() because hide() + // does not work if the item is already hidden, for example, + // in a collapsed fieldset. + object.css('display', 'none'); + } + } + } + } + + jQuery(trigger_id).change(function() { + // Trigger the internal change function + // the attr('id') is used because closures are more confusing + changeTrigger(trigger_id, bind_id); + }); + // Trigger initial reaction + changeTrigger(trigger_id, bind_id); + } + setChangeTrigger(trigger_id, bind_id); + } + } + } + + Drupal.behaviors.CToolsDependent = function (context) { + Drupal.CTools.dependent.autoAttach(); + + // Really large sets of fields are too slow with the above method, so this + // is a sort of hacked one that's faster but much less flexible. + $("select.ctools-master-dependent:not(.ctools-processed)") + .addClass('ctools-processed') + .change(function() { + var val = $(this).val(); + if (val == 'all') { + $('.ctools-dependent-all').show(0); + } + else { + $('.ctools-dependent-all').hide(0); + $('.ctools-dependent-' + val).show(0); + } + }) + .trigger('change'); + } +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/js/dropdown.js b/drupal/sites/default/boinc/modules/contrib/ctools/js/dropdown.js new file mode 100644 index 0000000000000000000000000000000000000000..ddf83f7d75410ee4802e3c5c70297098df5e6cfd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/js/dropdown.js @@ -0,0 +1,85 @@ +/** + * @file + * Implement a simple, clickable dropdown menu. + * + * See dropdown.theme.inc for primary documentation. + * + * The javascript relies on four classes: + * - The dropdown must be fully contained in a div with the class + * ctools-dropdown. It must also contain the class ctools-dropdown-no-js + * which will be immediately removed by the javascript; this allows for + * graceful degradation. + * - The trigger that opens the dropdown must be an a tag wit hthe class + * ctools-dropdown-link. The href should just be '#' as this will never + * be allowed to complete. + * - The part of the dropdown that will appear when the link is clicked must + * be a div with class ctools-dropdown-container. + * - Finally, ctools-dropdown-hover will be placed on any link that is being + * hovered over, so that the browser can restyle the links. + * + * This tool isn't meant to replace click-tips or anything, it is specifically + * meant to work well presenting menus. + */ + +(function ($) { + Drupal.behaviors.CToolsDropdown = function() { + $('div.ctools-dropdown:not(.ctools-dropdown-processed)') + .removeClass('ctools-dropdown-no-js') + .addClass('ctools-dropdown-processed') + .each(function() { + var $dropdown = $(this); + var open = false; + var hovering = false; + var timerID = 0; + + var toggle = function(close) { + // if it's open or we're told to close it, close it. + if (open || close) { + // If we're just toggling it, close it immediately. + if (!close) { + open = false; + $("div.ctools-dropdown-container", $dropdown).slideUp(100); + } + else { + // If we were told to close it, wait half a second to make + // sure that's what the user wanted. + // Clear any previous timer we were using. + if (timerID) { + clearTimeout(timerID); + } + timerID = setTimeout(function() { + if (!hovering) { + open = false; + $("div.ctools-dropdown-container", $dropdown).slideUp(100); + }}, 500); + } + } + else { + // open it. + open = true; + $("div.ctools-dropdown-container", $dropdown) + .animate({height: "show", opacity: "show"}, 100); + } + } + $("a.ctools-dropdown-link", $dropdown).click(function() { + toggle(); + return false; + }); + + $dropdown.hover( + function() { + hovering = true; + }, // hover in + function() { // hover out + hovering = false; + toggle(true); + return false; + }); + // @todo -- just use CSS for this noise. + $("div.ctools-dropdown-container a").hover( + function() { $(this).addClass('ctools-dropdown-hover'); }, + function() { $(this).removeClass('ctools-dropdown-hover'); } + ); + }); + }; +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/js/jump-menu.js b/drupal/sites/default/boinc/modules/contrib/ctools/js/jump-menu.js new file mode 100644 index 0000000000000000000000000000000000000000..ad8d30c65a7fc65d846bfd0f6c958f56f920bfe2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/js/jump-menu.js @@ -0,0 +1,33 @@ + +(function($) { + Drupal.behaviors.CToolsJumpMenu = function(context) { + $('.ctools-jump-menu-hide:not(.ctools-jump-menu-processed)') + .addClass('ctools-jump-menu-processed') + .hide(); + + $('.ctools-jump-menu-change:not(.ctools-jump-menu-processed)') + .addClass('ctools-jump-menu-processed') + .change(function() { + var loc = $(this).val(); + if (loc) { + location.href = loc; + } + return false; + }); + + $('.ctools-jump-menu-button:not(.ctools-jump-menu-processed)') + .addClass('ctools-jump-menu-processed') + .click(function() { + // Instead of submitting the form, just perform the redirect. + + // Find our sibling value. + var $select = $(this).parents('form').find('.ctools-jump-menu-select'); + var loc = $select.val(); + if (loc) { + location.href = loc; + } + return false; + }); + }; + +})(jQuery); \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/js/modal.js b/drupal/sites/default/boinc/modules/contrib/ctools/js/modal.js new file mode 100644 index 0000000000000000000000000000000000000000..b35c0675a82c5379c0cb11e8dc0770367450d5cd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/js/modal.js @@ -0,0 +1,475 @@ +/** + * @file + * + * Implement a modal form. + * + * @see modal.inc for documentation. + * + * This javascript relies on the CTools ajax responder. + */ + +(function ($) { + // Make sure our objects are defined. + Drupal.CTools = Drupal.CTools || {}; + Drupal.CTools.Modal = Drupal.CTools.Modal || {}; + + /** + * Display the modal + * + * @todo -- document the settings. + */ + Drupal.CTools.Modal.show = function(choice) { + var opts = {}; + + if (choice && typeof choice == 'string' && Drupal.settings[choice]) { + // This notation guarantees we are actually copying it. + $.extend(true, opts, Drupal.settings[choice]); + } + else if (choice) { + $.extend(true, opts, choice); + } + + var defaults = { + modalTheme: 'CToolsModalDialog', + throbberTheme: 'CToolsModalThrobber', + animation: 'show', + animationSpeed: 'fast', + modalSize: { + type: 'scale', + width: .8, + height: .8, + addWidth: 0, + addHeight: 0, + // How much to remove from the inner content to make space for the + // theming. + contentRight: 25, + contentBottom: 45 + }, + modalOptions: { + opacity: .55, + background: '#fff' + } + }; + + var settings = {}; + $.extend(true, settings, defaults, Drupal.settings.CToolsModal, opts); + + if (Drupal.CTools.Modal.currentSettings && Drupal.CTools.Modal.currentSettings != settings) { + Drupal.CTools.Modal.modal.remove(); + Drupal.CTools.Modal.modal = null; + } + + Drupal.CTools.Modal.currentSettings = settings; + + var resize = function(e) { + // When creating the modal, it actually exists only in a theoretical + // place that is not in the DOM. But once the modal exists, it is in the + // DOM so the context must be set appropriately. + var context = e ? document : Drupal.CTools.Modal.modal; + + if (Drupal.CTools.Modal.currentSettings.modalSize.type == 'scale') { + var width = $(window).width() * Drupal.CTools.Modal.currentSettings.modalSize.width; + var height = $(window).height() * Drupal.CTools.Modal.currentSettings.modalSize.height; + } + else { + var width = Drupal.CTools.Modal.currentSettings.modalSize.width; + var height = Drupal.CTools.Modal.currentSettings.modalSize.height; + } + + // Use the additionol pixels for creating the width and height. + $('div.ctools-modal-content', context).css({ + 'width': width + Drupal.CTools.Modal.currentSettings.modalSize.addWidth + 'px', + 'height': height + Drupal.CTools.Modal.currentSettings.modalSize.addHeight + 'px' + }); + $('div.ctools-modal-content .modal-content', context).css({ + 'width': (width - Drupal.CTools.Modal.currentSettings.modalSize.contentRight) + 'px', + 'height': (height - Drupal.CTools.Modal.currentSettings.modalSize.contentBottom) + 'px' + }); + } + + if (!Drupal.CTools.Modal.modal) { + Drupal.CTools.Modal.modal = $(Drupal.theme(settings.modalTheme)); + if (settings.modalSize.type == 'scale') { + $(window).bind('resize', resize); + } + } + + resize(); + + $('span.modal-title', Drupal.CTools.Modal.modal).html(Drupal.CTools.Modal.currentSettings.loadingText); + Drupal.CTools.Modal.modalContent(Drupal.CTools.Modal.modal, settings.modalOptions, settings.animation, settings.animationSpeed); + $('#modalContent .modal-content').html(Drupal.theme(settings.throbberTheme)); + }; + + /** + * Hide the modal + */ + Drupal.CTools.Modal.dismiss = function() { + if (Drupal.CTools.Modal.modal) { + Drupal.CTools.Modal.unmodalContent(Drupal.CTools.Modal.modal); + } + }; + + /** + * Provide the HTML to create the modal dialog. + */ + Drupal.theme.prototype.CToolsModalDialog = function () { + var html = '' + html += ' <div id="ctools-modal">' + html += ' <div class="ctools-modal-content">' // panels-modal-content + html += ' <div class="modal-header">'; + html += ' <a class="close" href="#">'; + html += Drupal.CTools.Modal.currentSettings.closeText + Drupal.CTools.Modal.currentSettings.closeImage; + html += ' </a>'; + html += ' <span id="modal-title" class="modal-title"> </span>'; + html += ' </div>'; + html += ' <div id="modal-content" class="modal-content">'; + html += ' </div>'; + html += ' </div>'; + html += ' </div>'; + + return html; + } + + /** + * Provide the HTML to create the throbber. + */ + Drupal.theme.prototype.CToolsModalThrobber = function () { + var html = ''; + html += ' <div id="modal-throbber">'; + html += ' <div class="modal-throbber-wrapper">'; + html += Drupal.CTools.Modal.currentSettings.throbber; + html += ' </div>'; + html += ' </div>'; + + return html; + }; + + /** + * Figure out what settings string to use to display a modal. + */ + Drupal.CTools.Modal.getSettings = function (object) { + var match = $(object).attr('class').match(/ctools-modal-(\S+)/); + if (match) { + return match[1]; + } + } + + /** + * Click function for modals that can be cached. + */ + Drupal.CTools.Modal.clickAjaxCacheLink = function () { + Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this)); + return Drupal.CTools.AJAX.clickAJAXCacheLink.apply(this); + }; + + /** + * Generic replacement click handler to open the modal with the destination + * specified by the href of the link. + */ + Drupal.CTools.Modal.clickAjaxLink = function () { + // show the empty dialog right away. + Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this)); + Drupal.CTools.AJAX.clickAJAXLink.apply(this); + if (!$(this).hasClass('ctools-ajaxing')) { + Drupal.CTools.Modal.dismiss(); + } + + return false; + }; + + /** + * Generic replacement click handler to open the modal with the destination + * specified by the href of the link. + */ + Drupal.CTools.Modal.clickAjaxButton = function() { + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } + + Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this)); + Drupal.CTools.AJAX.clickAJAXButton.apply(this); + if (!$(this).hasClass('ctools-ajaxing')) { + Drupal.CTools.Modal.dismiss(); + } + + return false; + }; + + /** + * Submit responder to do an AJAX submit on all modal forms. + */ + Drupal.CTools.Modal.submitAjaxForm = function(e) { + var url = $(this).attr('action'); + var form = $(this); + + setTimeout(function() { Drupal.CTools.AJAX.ajaxSubmit(form, url); }, 1); + return false; + } + + /** + * Bind links that will open modals to the appropriate function. + */ + Drupal.behaviors.ZZCToolsModal = function(context) { + // Bind links + // Note that doing so in this order means that the two classes can be + // used together safely. + $('a.ctools-use-modal-cache:not(.ctools-use-modal-processed)', context) + .addClass('ctools-use-modal-processed') + .click(Drupal.CTools.Modal.clickAjaxCacheLink) + .each(function () { + Drupal.CTools.AJAX.warmCache.apply(this); + }); + + $('a.ctools-use-modal:not(.ctools-use-modal-processed)', context) + .addClass('ctools-use-modal-processed') + .click(Drupal.CTools.Modal.clickAjaxLink); + + // Bind buttons + $('input.ctools-use-modal:not(.ctools-use-modal-processed), button.ctools-use-modal:not(.ctools-use-modal-processed)', context) + .addClass('ctools-use-modal-processed') + .click(Drupal.CTools.Modal.clickAjaxButton); + + // Bind submit links in the modal form. + $('#modal-content form:not(.ctools-use-modal-processed)', context) + .addClass('ctools-use-modal-processed') + .submit(Drupal.CTools.Modal.submitAjaxForm) + .bind('CToolsAJAXSubmit', Drupal.CTools.AJAX.ajaxSubmit); + + // add click handlers so that we can tell which button was clicked, + // because the AJAX submit does not set the values properly. + + $('#modal-content input[type="submit"]:not(.ctools-use-modal-processed), #modal-content button:not(.ctools-use-modal-processed)', context) + .addClass('ctools-use-modal-processed') + .click(function() { + if (Drupal.autocompleteSubmit && !Drupal.autocompleteSubmit()) { + return false; + } + + // Make sure it knows our button. + if (!$(this.form).hasClass('ctools-ajaxing')) { + this.form.clk = this; + } + }); + + // Bind a click handler to allow elements with the 'ctools-close-modal' + // class to close the modal. + $('.ctools-close-modal:not(.ctools-close-modal-processed)', context) + .addClass('ctools-close-modal-processed') + .click(function() { + Drupal.CTools.Modal.dismiss(); + return false; + }); + }; + + // The following are implementations of AJAX responder commands. + + /** + * AJAX responder command to place HTML within the modal. + */ + Drupal.CTools.AJAX.commands.modal_display = function(command) { + $('#modal-title').html(command.title); + $('#modal-content').html(command.output); + Drupal.attachBehaviors(); + } + + /** + * AJAX responder command to dismiss the modal. + */ + Drupal.CTools.AJAX.commands.modal_dismiss = function(command) { + Drupal.CTools.Modal.dismiss(); + $('link.ctools-temporary-css').remove(); + } + + /** + * Display loading + */ + Drupal.CTools.AJAX.commands.modal_loading = function(command) { + Drupal.CTools.AJAX.commands.modal_display({ + output: Drupal.theme(Drupal.CTools.Modal.currentSettings.throbberTheme), + title: Drupal.CTools.Modal.currentSettings.loadingText + }); + } + + /** + * modalContent + * @param content string to display in the content box + * @param css obj of css attributes + * @param animation (fadeIn, slideDown, show) + * @param speed (valid animation speeds slow, medium, fast or # in ms) + */ + Drupal.CTools.Modal.modalContent = function(content, css, animation, speed) { + // If our animation isn't set, make it just show/pop + if (!animation) { + animation = 'show'; + } + else { + // If our animation isn't "fadeIn" or "slideDown" then it always is show + if (animation != 'fadeIn' && animation != 'slideDown') { + animation = 'show'; + } + } + + if (!speed) { + speed = 'fast'; + } + + // Build our base attributes and allow them to be overriden + css = jQuery.extend({ + position: 'absolute', + left: '0px', + margin: '0px', + background: '#000', + opacity: '.55' + }, css); + + // Add opacity handling for IE. + css.filter = 'alpha(opacity=' + (100 * css.opacity) + ')'; + content.hide(); + + // if we already ahve a modalContent, remove it + if ( $('#modalBackdrop')) $('#modalBackdrop').remove(); + if ( $('#modalContent')) $('#modalContent').remove(); + + // position code lifted from http://www.quirksmode.org/viewport/compatibility.html + if (self.pageYOffset) { // all except Explorer + var wt = self.pageYOffset; + } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict + var wt = document.documentElement.scrollTop; + } else if (document.body) { // all other Explorers + var wt = document.body.scrollTop; + } + + // Get our dimensions + + // Get the docHeight and (ugly hack) add 50 pixels to make sure we dont have a *visible* border below our div + var docHeight = $(document).height() + 50; + var docWidth = $(document).width(); + var winHeight = $(window).height(); + var winWidth = $(window).width(); + if( docHeight < winHeight ) docHeight = winHeight; + + // Create our divs + $('body').append('<div id="modalBackdrop" style="z-index: 1000; display: none;"></div><div id="modalContent" style="z-index: 1001; position: absolute;">' + $(content).html() + '</div>'); + + // Keyboard and focus event handler ensures focus stays on modal elements only + modalEventHandler = function( event ) { + target = null; + if ( event ) { //Mozilla + target = event.target; + } else { //IE + event = window.event; + target = event.srcElement; + } + + var parents = $(target).parents().get(); + for (var i in $(target).parents().get()) { + var position = $(parents[i]).css('position'); + if (position == 'absolute' || position == 'fixed') { + return true; + } + } + if( $(target).filter('*:visible').parents('#modalContent').size()) { + // allow the event only if target is a visible child node of #modalContent + return true; + } + if ( $('#modalContent')) $('#modalContent').get(0).focus(); + return false; + }; + $('body').bind( 'focus', modalEventHandler ); + $('body').bind( 'keypress', modalEventHandler ); + + // Create our content div, get the dimensions, and hide it + var modalContent = $('#modalContent').css('top','-1000px'); + var mdcTop = wt + ( winHeight / 2 ) - ( modalContent.outerHeight() / 2); + var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2); + $('#modalBackdrop').css(css).css('top', 0).css('height', docHeight + 'px').css('width', docWidth + 'px').show(); + modalContent.css({top: mdcTop + 'px', left: mdcLeft + 'px'}).hide()[animation](speed); + + // Bind a click for closing the modalContent + modalContentClose = function(){close(); return false;}; + $('.close').bind('click', modalContentClose); + + // Close the open modal content and backdrop + function close() { + // Unbind the events + $(window).unbind('resize', modalContentResize); + $('body').unbind( 'focus', modalEventHandler); + $('body').unbind( 'keypress', modalEventHandler ); + $('.close').unbind('click', modalContentClose); + $(document).trigger('CToolsDetachBehaviors', $('#modalContent')); + + // Set our animation parameters and use them + if ( animation == 'fadeIn' ) animation = 'fadeOut'; + if ( animation == 'slideDown' ) animation = 'slideUp'; + if ( animation == 'show' ) animation = 'hide'; + + // Close the content + modalContent.hide()[animation](speed); + + // Remove the content + $('#modalContent').remove(); + $('#modalBackdrop').remove(); + }; + + // Move and resize the modalBackdrop and modalContent on resize of the window + modalContentResize = function(){ + // Get our heights + var docHeight = $(document).height(); + var docWidth = $(document).width(); + var winHeight = $(window).height(); + var winWidth = $(window).width(); + if( docHeight < winHeight ) docHeight = winHeight; + + // Get where we should move content to + var modalContent = $('#modalContent'); + var mdcTop = ( winHeight / 2 ) - ( modalContent.outerHeight() / 2); + var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2); + + // Apply the changes + $('#modalBackdrop').css('height', docHeight + 'px').css('width', docWidth + 'px').show(); + modalContent.css('top', mdcTop + 'px').css('left', mdcLeft + 'px').show(); + }; + $(window).bind('resize', modalContentResize); + + $('#modalContent').focus(); + }; + + /** + * unmodalContent + * @param content (The jQuery object to remove) + * @param animation (fadeOut, slideUp, show) + * @param speed (valid animation speeds slow, medium, fast or # in ms) + */ + Drupal.CTools.Modal.unmodalContent = function(content, animation, speed) + { + // If our animation isn't set, make it just show/pop + if (!animation) { var animation = 'show'; } else { + // If our animation isn't "fade" then it always is show + if (( animation != 'fadeOut' ) && ( animation != 'slideUp')) animation = 'show'; + } + // Set a speed if we dont have one + if ( !speed ) var speed = 'fast'; + + // Unbind the events we bound + $(window).unbind('resize', modalContentResize); + $('body').unbind('focus', modalEventHandler); + $('body').unbind('keypress', modalEventHandler); + $('.close').unbind('click', modalContentClose); + $(document).trigger('CToolsDetachBehaviors', $('#modalContent')); + + // jQuery magic loop through the instances and run the animations or removal. + content.each(function(){ + if ( animation == 'fade' ) { + $('#modalContent').fadeOut(speed,function(){$('#modalBackdrop').fadeOut(speed, function(){$(this).remove();});$(this).remove();}); + } else { + if ( animation == 'slide' ) { + $('#modalContent').slideUp(speed,function(){$('#modalBackdrop').slideUp(speed, function(){$(this).remove();});$(this).remove();}); + } else { + $('#modalContent').remove();$('#modalBackdrop').remove(); + } + } + }); + }; + +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/js/stylizer.js b/drupal/sites/default/boinc/modules/contrib/ctools/js/stylizer.js new file mode 100644 index 0000000000000000000000000000000000000000..19c011270b4316d2539464c533f6e7822cbf6714 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/js/stylizer.js @@ -0,0 +1,217 @@ + +(function ($) { + Drupal.CTools = Drupal.CTools || {}; + Drupal.CTools.Stylizer = {}; + + Drupal.CTools.Stylizer.addFarbtastic = function(context) { + // This behavior attaches by ID, so is only valid once on a page. + if ($('ctools_stylizer_color_scheme_form .color-form.Stylizer-processed').size()) { + return; + } + + var form = $('.color-form', context); + var inputs = []; + var hooks = []; + var locks = []; + var focused = null; + + // Add Farbtastic + $(form).prepend('<div id="placeholder"></div>').addClass('color-processed'); + var farb = $.farbtastic('#placeholder'); + + // Decode reference colors to HSL + /*var reference = Drupal.settings.Stylizer.reference.clone(); + for (i in reference) { + reference[i] = farb.RGBToHSL(farb.unpack(reference[i])); + } */ + + // Set up colorscheme selector + $('#edit-scheme', form).change(function () { + var colors = this.options[this.selectedIndex].value; + if (colors != '') { + colors = colors.split(','); + for (i in colors) { + callback(inputs[i], colors[i], false, true); + } + } + }); + + /** + * Shift a given color, using a reference pair (ref in HSL). + * + * This algorithm ensures relative ordering on the saturation and luminance + * axes is preserved, and performs a simple hue shift. + * + * It is also symmetrical. If: shift_color(c, a, b) == d, + * then shift_color(d, b, a) == c. + */ + function shift_color(given, ref1, ref2) { + // Convert to HSL + given = farb.RGBToHSL(farb.unpack(given)); + + // Hue: apply delta + given[0] += ref2[0] - ref1[0]; + + // Saturation: interpolate + if (ref1[1] == 0 || ref2[1] == 0) { + given[1] = ref2[1]; + } + else { + var d = ref1[1] / ref2[1]; + if (d > 1) { + given[1] /= d; + } + else { + given[1] = 1 - (1 - given[1]) * d; + } + } + + // Luminance: interpolate + if (ref1[2] == 0 || ref2[2] == 0) { + given[2] = ref2[2]; + } + else { + var d = ref1[2] / ref2[2]; + if (d > 1) { + given[2] /= d; + } + else { + given[2] = 1 - (1 - given[2]) * d; + } + } + + return farb.pack(farb.HSLToRGB(given)); + } + + /** + * Callback for Farbtastic when a new color is chosen. + */ + function callback(input, color, propagate, colorscheme) { + // Set background/foreground color + $(input).css({ + backgroundColor: color, + 'color': farb.RGBToHSL(farb.unpack(color))[2] > 0.5 ? '#000' : '#fff' + }); + + // Change input value + if (input.value && input.value != color) { + input.value = color; + + // Update locked values + if (propagate) { + var i = input.i; + for (j = i + 1; ; ++j) { + if (!locks[j - 1] || $(locks[j - 1]).is('.unlocked')) break; + var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); + callback(inputs[j], matched, false); + } + for (j = i - 1; ; --j) { + if (!locks[j] || $(locks[j]).is('.unlocked')) break; + var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); + callback(inputs[j], matched, false); + } + + } + + // Reset colorscheme selector + if (!colorscheme) { + resetScheme(); + } + } + + } + + /** + * Reset the color scheme selector. + */ + function resetScheme() { + $('#edit-scheme', form).each(function () { + this.selectedIndex = this.options.length - 1; + }); + } + + // Focus the Farbtastic on a particular field. + function focus() { + var input = this; + // Remove old bindings + focused && $(focused).unbind('keyup', farb.updateValue) + .unbind('keyup', resetScheme) + .parent().removeClass('item-selected'); + + // Add new bindings + focused = this; + farb.linkTo(function (color) { callback(input, color, true, false); }); + farb.setColor(this.value); + $(focused).keyup(farb.updateValue).keyup(resetScheme) + .parent().addClass('item-selected'); + } + + // Initialize color fields + $('#palette input.form-text', form) + .each(function () { + // Extract palette field name + this.key = this.id.substring(13); + + // Link to color picker temporarily to initialize. + farb.linkTo(function () {}).setColor('#000').linkTo(this); + + // Add lock + var i = inputs.length; + if (inputs.length) { + var lock = $('<div class="lock"></div>').toggle( + function () { + $(this).addClass('unlocked'); + $(hooks[i - 1]).attr('class', + locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook up' : 'hook' + ); + $(hooks[i]).attr('class', + locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook down' : 'hook' + ); + }, + function () { + $(this).removeClass('unlocked'); + $(hooks[i - 1]).attr('class', + locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook both' : 'hook down' + ); + $(hooks[i]).attr('class', + locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook both' : 'hook up' + ); + } + ); + $(this).after(lock); + locks.push(lock); + }; + + // Add hook + var hook = $('<div class="hook"></div>'); + $(this).after(hook); + hooks.push(hook); + + $(this).parent().find('.lock').click(); + this.i = i; + inputs.push(this); + }) + .focus(focus); + + $('#palette label', form); + + // Focus first color + focus.call(inputs[0]); + }; + + Drupal.behaviors.CToolsColorSettings = function() { + $('.ctools-stylizer-color-edit:not(.ctools-color-processed)') + .addClass('ctools-color-processed') + .each(function() { + Drupal.CTools.Stylizer.addFarbtastic('#' + $(this).attr('id')); + }); + + $('div.form-item div.ctools-style-icon:not(.ctools-color-processed)') + .addClass('ctools-color-processed') + .click(function() { + $widget = $('input', $(this).parent()); + // Toggle if a checkbox, turn on if a radio. + $widget.attr('checked', !$widget.attr('checked') || $widget.is('input[type=radio]')); + }); + } +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/css/page-manager.css b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/css/page-manager.css new file mode 100644 index 0000000000000000000000000000000000000000..44985780bb761a9513db5cabafeca40a35310a2b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/css/page-manager.css @@ -0,0 +1,341 @@ +body form#page-manager-list-pages-form { + margin: 0 0 20px 0; +} + +#page-manager-list-pages-form .form-item { + padding-right: 1em; /* LTR */ + float: left; /* LTR */ + margin-top: 0; + margin-bottom: 0; +} + +#page-manager-list-pages { + width: 100%; +} + +#edit-order-wrapper { + clear: left; /* LTR */ +} + +#edit-pages-apply, +#edit-pages-reset { + margin-top: 1.65em; + float: left; /* LTR */ +} + +#page-manager-edit { + margin-top: 1em; +} + +#page-manager-edit table { + width: 100%; +} + +#page-manager-edit table tr.even { + background-color: #fafafa; +} + +#page-manager-list-pages tr.page-manager-disabled { + color: #999; +} + +#page-manager-list-pages tr.page-manager-locked td.page-manager-page-name { + font-style: italic; + color: green; + padding-left: 22px; /* LTR */ + background: url(../images/locked.png) no-repeat scroll left center; /* LTR */ +} + +#page-manager-list-pages tr.page-manager-locked-other td.page-manager-page-name { + font-style: italic; + color: red; + padding-left: 22px; /* LTR */ + background: url(../images/locked-other.png) no-repeat scroll left center; /* LTR */ +} + +#page-manager-edit .page-manager-wrapper { + margin: 0; + padding: 0 0 0 149px; + color: #494949; +} + +#page-manager-edit .page-manager-tabs { + border: 1px solid #aaa; +} + +#page-manager-edit .page-manager-edit-operations { + float: left; /* LTR */ + width: 150px; + margin-left: -150px; + margin-top: -1px; + height: 100%; + font-size: 90%; +} + +#page-manager-edit .page-manager-edit-operations .inside { + border-top: 1px solid #aaa; + border-bottom: 1px solid #aaa; +} + +#page-manager-edit .page-manager-edit-operations ul { + margin-top: 0; + margin-bottom: 0; + padding: 0; + margin-left: 0; +} + +#page-manager-edit .page-manager-edit-operations li { + list-style: none; + background: #F6F6F6; + border-top: 1px solid #aaa; + border-left: 1px solid #aaa; + border-right: 1px solid #aaa; + padding: 0 0 0 0; + margin: 0; + line-height: 2em; +} + +#page-manager-edit .page-manager-edit-operations li.active, +#page-manager-edit .page-manager-edit-operations li.active-group .page-manager-group-title { + background: #FFFFFF url(../images/arrow-active.png) no-repeat scroll right center; +} + +#page-manager-edit .page-manager-edit-operations li.changed, +#page-manager-edit .page-manager-edit-operations li.changed-group .page-manager-group-title { + background-color: #ffe; + font-weight: bold; +} + +/** provide a reset for non active stray paths */ +#page-manager-edit .page-manager-edit-operations li.active-group li.not-active .page-manager-group-title, +#page-manager-edit .page-manager-edit-operations li.changed-group li.not-changed .page-manager-group-title { + background: #F6F6F6; +} + +#page-manager-edit .page-manager-edit-operations li.active { + border-right: 1px solid white; +} + +#page-manager-edit .page-manager-edit-operations li.active a, +#page-manager-edit .page-manager-edit-operations li.active a:hover { + background: #FFFFFF url(../images/arrow-active.png) no-repeat scroll right center; + color: #000000; + font-weight: bold; +} + +#page-manager-edit .page-manager-edit-operations li.operation-first { + border-top: none; +} + +#page-manager-edit .page-manager-edit-operations li li.operation-first { + border-top: 1px solid #aaa; +} + +#page-manager-edit .page-manager-edit-operations li a { + display: block; + padding: 0 0 0 .5em; + color: #494949; +} + +#page-manager-edit .page-manager-edit-operations li a:hover { + background-color: #eee; + text-decoration: none; +} + +#page-manager-edit .ctools-collapsible-container { + display: inline-block; + position: relative; + *float: left; /* LTR */ + width: 100%; +} + +#page-manager-edit .page-manager-edit-operations li .ctools-collapsible-handle:hover { + background-color: #eee; +} + +#page-manager-edit .page-manager-edit-operations li li { + border-right: none; + border-left: none; + margin-left: 1em; +} + +#page-manager-edit .page-manager-edit-operations li ul { +} + +#page-manager-edit .page-manager-group-title { + line-height: 2em; + font-weight: bold; + padding: 0 0 0 .5em; +} + +/* Change the position of the arrow on the dropdown to look nicer with our defaults. */ +#page-manager-edit .page-manager-edit-operations .ctools-toggle { + background-position: 0 9px; + width: 10px; +} + +#page-manager-edit .page-manager-ajax-pad { + float: left; /* LTR */ + width: 100%; + border-left: none; + height: 100%; + background: white; +} + +/** A riser to force the ajax pad to a minimum height. **/ +#page-manager-edit .page-manager-ajax-pad .page-manager-riser { + width: 1px; + float: right; /* LTR */ + height: 400px; +} + +#page-manager-edit .page-manager-ajax-pad .page-manager-riser span { + display: none; +} + +#page-manager-edit .page-manager-ajax-pad .content-title { + font-weight: bold; + font-size: 120%; + background-color: #fafafa; + border-bottom: 1px solid #aaa; + border-left: 1px solid #aaa; + margin-left: -1px; + padding: 2px 5px 2px 20px; +} + +#page-manager-edit .actions { + padding: 0 0 0 20px; +} + +#page-manager-edit .primary-actions li { + border-top: 1px solid #aaa; +} + +#page-manager-edit .secondary-actions { + border-bottom: 1px solid #aaa; +} + +#page-manager-edit .handler-actions { + float: right; /* LTR */ +} + +#page-manager-edit .actions .page-manager-group-title { + float: left; /* LTR */ + padding-left: 0; +} + +#page-manager-edit .actions ul { + float: right; /* LTR */ + text-align: right; /* LTR */ + padding: 0; + margin: 0; + border-right: 1px solid #aaa; +} + +#page-manager-edit .handler-title .actions ul { + border-right: none; +} + +#page-manager-edit .actions li { + float: left; /* LTR */ + background: none; + list-style: none; + border-left: 1px solid #aaa; + margin: 0; + padding: 0; +} + +#page-manager-edit .actions ul li.operation-last { + border-right: none; +} + +#page-manager-edit .actions li a:hover { + background-color: #eee; + text-decoration: none; +} + +#page-manager-edit .actions li a { + display: block; + padding: 0.2em 0.5em; + color:#0062A0; + background-color: #F6F6F6; +} + +#page-manager-edit .page-manager-changed { + float: right; /* LTR */ + font-style: italic; + color: #f93; + padding-left: 1em; + padding-right: 22px; + background: url(../images/locked.png) no-repeat scroll right center; +} + +#page-manager-edit .page-manager-ajax-pad .content-content { + padding: .5em 20px; +} + +#page-manager-edit .page-manager-ajax-pad textarea { + width: 100%; +} + +#page-manager-edit .changed-notification { + border: 1px solid #aaa; + background-color: #ffe; + color: #494949; + padding: 1em; + margin-top: 1em; +} + +#page-manager-edit .ctools-locked { + margin-bottom: 2em; +} + +#page-manager-page-summary .title { + font-weight: bold; + font-size: 160%; +} + +#page-manager-page-summary .handler-summary { +} + +#page-manager-page-summary .page-summary-operation { + text-align: right; +} + +#page-manager-page-summary .page-summary-label { + width: 8em; + font-weight: bold; +} + + +.handler-summary dl { + margin: 0; +} + +.handler-summary dt { + margin: 0; + padding: 0; +} + +.handler-summary dd { + margin: 0; +} + +.handler-summary ol { + margin: 0; +} + +.handler-summary .handler-title { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + background: #fafafa; + padding: 0 0 0 5px; + margin-top: .5em; +} + +.handler-summary .handler-title .title-label { + font-weight: bold; + font-size: 120%; + line-height: 1.75em; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/about.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/about.html new file mode 100644 index 0000000000000000000000000000000000000000..fa58acafbb1c3fd767706439cb597edc6a4b8153 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/about.html @@ -0,0 +1,11 @@ +The Page Manager module creates and manages pages in your Drupal site. Pages are defined as items that have a path and provide output to the user. It is a complete round trip from getting user input to providing user output. + +There are two types of pages that the Page Manager currently supports: +<dl> +<dt>Custom pages</dt> +<dd>Custom pages are defined completely by the administrator. Their path, access control and visible menu characteristics are completely arbitrary.</dd> +<dt>System pages</dt> +<dd>System pages are defined by Drupal and Drupal modules. They primarily override pre-existing pages to provide different functionality. They often do not allow such features as access control in favor of what already exists, and they will usually 'fall back' to default Drupal behavior. +</dl> + +Both types of pages figure out what to show the user by using <strong>Variants</strong>. Variants are output handlers, and every page should have at least one. Most pages will simply have only one. Pages with multiple variants will choose one and only one Variant to display content to the user and will use the <strong>Selection Rules</strong> to figure out which Variant to display. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task-handler.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task-handler.html new file mode 100644 index 0000000000000000000000000000000000000000..4544a2a864a759446765b8990628437d5f91e4fb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task-handler.html @@ -0,0 +1,43 @@ +task handler definition: + title -- visible title of the task handler. + description -- description of the task handler. + task type -- The type of the task this handler can service. + render -- callback of the function to render the handler. The arguments to this callback are specific to the task type. + admin title -- callback to render the admin title as this handler is listed. + params: $handler, $task, $subtask_id + admin summary -- callback to render what's in the collapsible info as the handler is listed. Optional. + params: $handler, $task, $subtask_id + default conf -- either an array() of default conf data or a callback that returns an array. + params: $handler, $task, $subtask_id + save -- callback to call just prior to the task handler being saved so it can adjust its data. + params: &$handler, $update (as drupal_write_record would receive) + export -- callback to call just prior to the task being exported. It should return text to append to the export if necessary. + params: &$handler, $indent + + forms => array( + 'id' => array( + 'form' => form callback (receives $form, $form_state) + 'submit' => submit callback + 'validate' => validate callback + 'include' => an optional file to include to get functionality for this form. Must include full path. + 'no return' => hide the 'return' button, meaning that the form requires extra steps if submitted + 'alternate next' => an alternate next form. Used for hidden edit forms that don't have tabs. + 'no blocks' => if TRUE, use Drupal's mechanism to not render blocks for this form. + ) + ) + ), + + 'add forms' => array( + 'form1', => t('form title'), + 'form2', => t('form title'), + // ...etc.../ +), + 'edit forms' => array( + 'id' => t('tab name'), + 'id2' => t('tab name'), + ), + + If a form name is blank it is a 'hidden' form -- it has no tab but can still be reached. + + +Notes: Because #required validation cannot be skipped when clicking cancel, please don't use it. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task-type.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task-type.html new file mode 100644 index 0000000000000000000000000000000000000000..eb87265f6264505e8e91a1cb5b37dca6a50a705a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task-type.html @@ -0,0 +1,2 @@ + +defines a task type, grouping tasks together and providing a common UI for them. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task.html new file mode 100644 index 0000000000000000000000000000000000000000..cd6e3d0cbc495c4fdf0c0e5ea84224023ea54485 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/api-task.html @@ -0,0 +1,38 @@ +task definition: + title -- visible title of the task. + description -- description of the task. + hook menu -- function to delegate from hook_menu. Params: &$items, $task + hook menu alter -- function to delegate from hook_menu_alter. Params: &$items, $task + hook theme -- function to delegate from hook_theme. Params: &$items, $task + + admin name -- if set an admin menu will appear in the delegator UI + admin description -- to describe the admin menu + + admin access callback -- if set, the callback to use to determine administrative + access to this task. Defaults to user_access. Note that this is required even + if delegator isn't handling administration, since this gets used to on handler + edit forms. + admin access arguments -- If set, the arguments to use to determine administrative + access to this task. Defaults to array('administer delegator'); + + type -- The type of the task, used to determine which handlers can service it. + + subtasks -- can be TRUE in which case it supports subtasks with the default + configuration or a string (array?) with callbacks to fetch subtask data. + subtask callback -- A callback which returns just one subtask. Param: $task, $subtask_id + subtasks callback -- A callback which returns an array of all subtasks. + This MUST return an array, even if it's empty.Param: $task + + default handlers -- If the task contains any default handlers, they can be included here. + +task names must not contain a - as that is used to separate the task name from the subtask ID. + +subtasks implement data very similar to their parent task. In particular, they +implement the following items exactly like their task: + hook menu + hook menu alter + description + admin name + admin description + admin access callback + admin access arguments diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-access.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-access.html new file mode 100644 index 0000000000000000000000000000000000000000..a2643c28c44e50046cd53476b79eb00ef0306f16 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-access.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528072">http://drupal.org/node/528072</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-arguments.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-arguments.html new file mode 100644 index 0000000000000000000000000000000000000000..516a4292b95039e976c02ba8f145804e1beb30ce --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-arguments.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528058">http://drupal.org/node/528058</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-menu.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-menu.html new file mode 100644 index 0000000000000000000000000000000000000000..48cf9c3976d892215d0ae73055314634799a4282 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages-menu.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528078">http://drupal.org/node/528078</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages.html new file mode 100644 index 0000000000000000000000000000000000000000..18e66d4bef925c51a07e7673e79cf74df883d2ab --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/custom-pages.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528050">http://drupal.org/node/528050</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-create.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-create.html new file mode 100644 index 0000000000000000000000000000000000000000..a3d295e388f121663fc6ca48976abec1ef15d6ee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-create.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528038">http://drupal.org/node/528038</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-custom-nodes.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-custom-nodes.html new file mode 100644 index 0000000000000000000000000000000000000000..d62eb0f32a2ca2a5dc5b4c4956c5f2c24bfca4e0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-custom-nodes.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528044">http://drupal.org/node/528044</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-custom-vocabulary.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-custom-vocabulary.html new file mode 100644 index 0000000000000000000000000000000000000000..7148cd96a3c43bb613edb778f5f0030cda53dc08 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-custom-vocabulary.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528046">http://drupal.org/node/528046</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-members.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-members.html new file mode 100644 index 0000000000000000000000000000000000000000..87b21227ca1bf718c9807056b4fa87208c3d9aad --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-members.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528040">http://drupal.org/node/528040</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-page-list.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-page-list.html new file mode 100644 index 0000000000000000000000000000000000000000..d60bea4ad0bc9cc0f2d86d5f6426be6ba2f05d0d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started-page-list.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528036">http://drupal.org/node/528036</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started.html new file mode 100644 index 0000000000000000000000000000000000000000..4e4f24ae8f3ec30c0ed038f1f3419b36b0371f8d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/getting-started.html @@ -0,0 +1,15 @@ + +Note: this page is currently very preliminary. Please visit <a href="http://drupal.org/node/528034">http://drupal.org/node/528034</a> to help provide this documentation page! + +This is a quick summary: + +<ul> +<li>Visit administer >> site building >> pages to get to the primary page manager interface.</li> +<li>You can add custom pages for your basic landing pages, front pages, whatever you like for normal content display.</li> +<li>You can use the system pages to create finer control of how taxonomy vocabularies, nodes and user profiles are displayed.</li> +<li>When you add your first custom page, do not bother with the optional features. You will not need these until you get to more advanced tasks.</li> +<li>The selection rules are the key to creating node displays for just one node type.</li> +<li>Everything in this system is pluggable. A little PHP knowledge and exploration of the plugins directories can take you a long way.</li> +</ul> + + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/page-task-type.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/page-task-type.html new file mode 100644 index 0000000000000000000000000000000000000000..c382c76ff2e76fde8653bc3ea72304e55ee92cba --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/page-task-type.html @@ -0,0 +1,4 @@ + +Additional 'task' keys support: + +operations -- a list of operations suitable for theme('links') \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/page_manager.help.ini b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/page_manager.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..05cadb482e3bcaa323bb8de6e74371174a21bf50 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/page_manager.help.ini @@ -0,0 +1,59 @@ +[advanced help settings] +line break = TRUE + +[about] +title = About Page Manager +weight = -100 + +[getting-started] +title = Getting Started +weight = -80 + +[getting-started-page-list] +title = The page list +weight = -90 +parent = getting-started + +[getting-started-create] +title = Creating a page +weight = -80 +parent = getting-started + +[getting-started-members] +title = Tutorial: Make a page that looks different for members +weight = -70 +parent = getting-started + +[getting-started-custom-nodes] +title = Tutorial: Customize the look of a single node type +weight = -60 +parent = getting-started + +[getting-started-custom-vocabulary] +title = Tutorial: Customize the look of a single taxonomy vocabulary +weight = -50 +parent = getting-started + +[custom-pages] +title = Custom pages +weight = -50 + +[custom-pages-arguments] +title = Arguments +weight = -100 +parent = custom-pages + +[custom-pages-access] +title = Access control +weight = -90 +parent = custom-pages + +[custom-pages-menu] +title = Menu items +weight = -80 +parent = custom-pages + +[variants] +title = Variants +weight = -40 + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/variants.html b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/variants.html new file mode 100644 index 0000000000000000000000000000000000000000..48cf9c3976d892215d0ae73055314634799a4282 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/help/variants.html @@ -0,0 +1,2 @@ + +Please visit <a href="http://drupal.org/node/528078">http://drupal.org/node/528078</a> to help provide this documentation page. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/arrow-active.png b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/arrow-active.png new file mode 100644 index 0000000000000000000000000000000000000000..3bbd3c27f29f9a1781276a2ae8faa7afd5d2d36e Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/arrow-active.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/locked-other.png b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/locked-other.png new file mode 100644 index 0000000000000000000000000000000000000000..b84a154e8b41ae4f0ce9ea97fa9de7ab8534284a Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/locked-other.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/locked.png b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/locked.png new file mode 100644 index 0000000000000000000000000000000000000000..2116eb1c810d4f76eefeebb920f3764ea443c0fb Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/images/locked.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/js/page-list.js b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/js/page-list.js new file mode 100644 index 0000000000000000000000000000000000000000..16b52911dca41f4c763849b1bec92f4dd956b81d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/js/page-list.js @@ -0,0 +1,44 @@ + +/** + * Provide some extra responses for the page list so we can have automatic + * on change. + */ + +Drupal.behaviors.PageManagerList = function() { + var timeoutID = 0; + $('form#page-manager-list-pages-form select:not(.pm-processed)') + .addClass('pm-processed') + .change(function() { + $('#edit-pages-apply').click(); + }); + $('form#page-manager-list-pages-form input[type=text]:not(.pm-processed)') + .addClass('pm-processed') + .keyup(function(e) { + switch (e.keyCode) { + case 16: // shift + case 17: // ctrl + case 18: // alt + case 20: // caps lock + case 33: // page up + case 34: // page down + case 35: // end + case 36: // home + case 37: // left arrow + case 38: // up arrow + case 39: // right arrow + case 40: // down arrow + case 9: // tab + case 13: // enter + case 27: // esc + return false; + default: + if (!$('#edit-pages-apply').hasClass('ctools-ajaxing')) { + if ((timeoutID)) { + clearTimeout(timeoutID); + } + + timeoutID = setTimeout(function() { $('#edit-pages-apply').click(); }, 300); + } + } + }); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.admin.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..ecd253141b34bdc91075dfad35a44e580822570e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.admin.inc @@ -0,0 +1,1826 @@ +<?php + +/** + * @file + * Administrative functions for the page manager. + * + * This provides the UI to list, create, edit and delete pages, though much + * of this is delegated through to individual tasks. + */ + +/** + * Output a list of pages that are managed. + */ +function page_manager_list_page($js = NULL) { + // Prevent this page from showing up when random other links fail. + if ($js && $js != 'ajax' && $js != 'nojs') { + return drupal_not_found(); + } + + // TRUE if 'ajax', FALSE if otherwise. + $js = $js == 'ajax'; + + if (module_exists('advanced_help') && !$js) { + drupal_set_message(theme('advanced_help_topic', 'page_manager', 'getting-started', t('See the getting started guide for more information.'))); + } + + $tasks = page_manager_get_tasks_by_type('page'); + $pages = array('operations' => array(), 'tasks' => array()); + + page_manager_get_pages($tasks, $pages); + + // Add lock icon to all locked tasks. + global $user; + ctools_include('object-cache'); + $locks = ctools_object_cache_test_objects('page_manager_page', $pages['tasks']); + foreach ($locks as $task_name => $lock) { + if ($lock->uid == $user->uid) { + $pages['rows'][$task_name]['class'] .= ' page-manager-locked'; + $pages['rows'][$task_name]['title'] = t('This page is currently locked for editing by you. Nobody else may edit this page until these changes are saved or canceled.'); + } + else { + $pages['rows'][$task_name]['class'] .= ' page-manager-locked-other'; + $pages['rows'][$task_name]['title'] = t('This page is currently locked for editing by another user. You may not edit this page without breaking the lock.'); + } + } + + $input = $_POST; + + // Respond to a reset command by clearing session and doing a drupal goto + // back to the base URL. + if (isset($input['op']) && $input['op'] == t('Reset')) { + unset($_SESSION['page_manager']['#admin']); + if (!$js) { + return drupal_goto($_GET['q']); + } + // clear everything but form id, form build id and form token: + $keys = array_keys($input); + foreach ($keys as $id) { + if ($id != 'form_id' && $id != 'form_build_id' && $id != 'form_token') { + unset($input[$id]); + } + } + $replace_form = TRUE; + } + if (count($input) <= 1) { + if (isset($_SESSION['page_manager']['#admin']) && is_array($_SESSION['page_manager']['#admin'])) { + $input = $_SESSION['page_manager']['#admin']; + } + } + else { + $_SESSION['page_manager']['#admin'] = $input; + unset($_SESSION['page_manager']['#admin']['q']); + } + + $form_state = array( + 'pages' => &$pages, + 'input' => $input, + 'rerender' => TRUE, + 'no_redirect' => TRUE, + ); + + // This form will sort and filter the pages. + ctools_include('form'); + $form = ctools_build_form('page_manager_list_pages_form', $form_state); + + $header = array( + array('data' => t('Type'), 'class' => 'page-manager-page-type'), + array('data' => t('Name'), 'class' => 'page-manager-page-name'), + array('data' => t('Title'), 'class' => 'page-manager-page-title'), + array('data' => t('Path'), 'class' => 'page-manager-page-path'), + array('data' => t('Storage'), 'class' => 'page-manager-page-storage'), + ); + + $header[] = array('data' => t('Operations'), 'class' => 'page-manager-page-operations'); + $table = theme('table', $header, $pages['rows'], array('id' => 'page-manager-list-pages')); + + $operations = '<div id="page-manager-links" class="links">' . theme('links', $pages['operations']) . '</div>'; + + drupal_add_css(drupal_get_path('module', 'page_manager') . '/css/page-manager.css'); + + if (!$js) { + return $form . $table . $operations; + } + + ctools_include('ajax'); + $commands = array(); + $commands[] = ctools_ajax_command_replace('#page-manager-list-pages', $table); + if (!empty($replace_form)) { + $commands[] = ctools_ajax_command_replace('#page-manager-list-pages-form', $form); + } + ctools_ajax_render($commands); +} + +/** + * Sort tasks into buckets based upon whether or not they have subtasks. + */ +function page_manager_get_pages($tasks, &$pages, $task_id = NULL) { + foreach ($tasks as $id => $task) { + if (empty($task_id) && !empty($task['page operations'])) { + $pages['operations'] = array_merge($pages['operations'], $task['page operations']); + } + + // If a type has subtasks, add its subtasks in its own table. + if (!empty($task['subtasks'])) { + page_manager_get_pages(page_manager_get_task_subtasks($task), $pages, $task['name']); + continue; + } + + if (isset($task_id)) { + $task_name = page_manager_make_task_name($task_id, $task['name']); + } + else { + $task_name = $task['name']; + } + + $class = 'page-task-' . $id; + if (isset($task['row class'])) { + $class .= ' ' . $task['row class']; + } + + if (!empty($task['disabled'])) { + $class .= ' page-manager-disabled'; + } + + $path = array(); + $visible_path = ''; + if (!empty($task['admin path'])) { + foreach (explode('/', $task['admin path']) as $bit) { + if ($bit[0] != '!') { + $path[] = $bit; + } + } + + $path = implode('/', $path); + if (empty($task['disabled']) && strpos($path, '%') === FALSE) { + $visible_path = l('/' . $task['admin path'], $path); + } + else { + $visible_path = '/' . $task['admin path']; + } + } + + $row = array('data' => array(), 'class' => $class, 'title' => strip_tags($task['admin description'])); + + $type = isset($task['admin type']) ? $task['admin type'] : t('System'); + $pages['types'][$type] = $type; + $row['data']['type'] = array('data' => $type, 'class' => 'page-manager-page-type'); + + $row['data']['name'] = array('data' => $task_name, 'class' => 'page-manager-page-name'); + $row['data']['title'] = array('data' => $task['admin title'], 'class' => 'page-manager-page-title'); + $row['data']['path'] = array('data' => $visible_path, 'class' => 'page-manager-page-path'); + + $storage = isset($task['storage']) ? $task['storage'] : t('In code'); + $pages['storages'][$storage] = $storage; + $row['data']['storage'] = array('data' => $storage, 'class' => 'page-manager-page-storage'); + + +/* + if (empty($task['disabled'])) { + $item = menu_get_item($path); + if (empty($item)) { + dsm($path); + } + else { + dsm($item); + } + } +*/ + $operations = array( + array( + 'title' => t('Edit'), + 'href' => page_manager_edit_url($task_name), + ), + ); + + if (!empty($task['enable callback'])) { + if (!empty($task['disabled'])) { + $operations[] = array( + 'title' => t('Enable'), + 'href' => 'admin/build/pages/nojs/enable/' . $task_name, + 'query' => array('token' => drupal_get_token($task_name)), + ); + } + else { + $operations[] = array( + 'title' => t('Disable'), + 'href' => 'admin/build/pages/nojs/disable/' . $task_name, + 'query' => array('token' => drupal_get_token($task_name)), + ); + } + } + + $row['data']['operations'] = array('data' => theme('links', $operations), 'class' => 'page-manager-page-operations'); + + $pages['disabled'][$task_name] = !empty($task['disabled']); + $pages['tasks'][] = $task_name; + $pages['rows'][$task_name] = $row; + } +} + +/** + * Provide a form for sorting and filtering the list of pages. + */ +function page_manager_list_pages_form(&$form_state) { + // This forces the form to *always* treat as submitted which is + // necessary to make it work. + if (empty($_POST)) { + $form["#programmed"] = TRUE; + } + $form['#action'] = url('admin/build/pages/nojs/', array('absolute' => TRUE)); + if (!variable_get('clean_url', FALSE)) { + $form['q'] = array( + '#type' => 'hidden', + '#value' => $_GET['q'], + ); + } + + $all = array('all' => t('<All>')); + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Type'), + '#options' => $all + $form_state['pages']['types'], + '#default_value' => 'all', + ); + + $form['storage'] = array( + '#type' => 'select', + '#title' => t('Storage'), + '#options' => $all + $form_state['pages']['storages'], + '#default_value' => 'all', + ); + + $form['disabled'] = array( + '#type' => 'select', + '#title' => t('Enabled'), + '#options' => $all + array('0' => t('Enabled'), '1' => t('Disabled')), + '#default_value' => 'all', + ); + + $form['search'] = array( + '#type' => 'textfield', + '#title' => t('Search'), + ); + + $form['order'] = array( + '#type' => 'select', + '#title' => t('Sort by'), + '#options' => array( + 'disabled' => t('Enabled, title'), + 'title' => t('Title'), + 'name' => t('Name'), + 'path' => t('Path'), + 'type' => t('Type'), + 'storage' => t('Storage'), + ), + '#default_value' => 'disabled', + ); + + $form['sort'] = array( + '#type' => 'select', + '#title' => t('Order'), + '#options' => array( + 'asc' => t('Up'), + 'desc' => t('Down'), + ), + '#default_value' => 'asc', + ); + + $form['submit'] = array( + '#name' => '', // so it won't in the $_GET args + '#type' => 'submit', + '#id' => 'edit-pages-apply', + '#value' => t('Apply'), + '#attributes' => array('class' => 'ctools-use-ajax'), + ); + + $form['reset'] = array( + '#type' => 'submit', + '#id' => 'edit-pages-reset', + '#value' => t('Reset'), + '#attributes' => array('class' => 'ctools-use-ajax'), + ); + + ctools_add_js('ajax-responder'); + drupal_add_js('misc/jquery.form.js'); + drupal_add_js(drupal_get_path('module', 'page_manager') . '/js/page-list.js'); + $form['#theme'] = array('page_manager_list_pages_form'); + return $form; +} + +/** + * Accept submission from the page manager sort/filter form and apply it + * to the list of pages. + */ +function page_manager_list_pages_form_submit(&$form, &$form_state) { + // Filter and re-sort the pages. + + // This is a copy. + $rows = $form_state['pages']['rows']; + + $sorts = array(); + foreach ($rows as $name => $data) { + // Filter + if ($form_state['values']['type'] != 'all' && $form_state['values']['type'] != $data['data']['type']['data']) { + continue; + } + + if ($form_state['values']['storage'] != 'all' && $form_state['values']['storage'] != $data['data']['storage']['data']) { + continue; + } + + if ($form_state['values']['disabled'] != 'all' && $form_state['values']['disabled'] != $form_state['pages']['disabled'][$name]) { + continue; + } + + if ($form_state['values']['search'] && + strpos($data['data']['name']['data'], $form_state['values']['search']) === FALSE && + strpos($data['data']['path']['data'], $form_state['values']['search']) === FALSE && + strpos($data['data']['title']['data'], $form_state['values']['search']) === FALSE) { + continue; + } + // Set up sorting + switch ($form_state['values']['order']) { + case 'disabled': + $sorts[$name] = !$form_state['pages']['disabled'][$name] . $data['data']['title']['data']; + break; + case 'title': + $sorts[$name] = $data['data']['title']['data']; + break; + case 'name': + $sorts[$name] = $data['data']['name']['data']; + break; + case 'path': + $sorts[$name] = $data['data']['path']['data']; + break; + case 'type': + $sorts[$name] = $data['data']['type']['data']; + break; + case 'storage': + $sorts[$name] = $data['data']['storage']['data']; + break; + } + } + + // Now actually sort + if ($form_state['values']['sort'] == 'desc') { + arsort($sorts); + } + else { + asort($sorts); + } + + // Nuke the original. + $form_state['pages']['rows'] = array(); + // And restore. + foreach ($sorts as $name => $title) { + $form_state['pages']['rows'][$name] = $rows[$name]; + } + +} + +/** + * Render the edit page for a a page, custom or system. + */ +function page_manager_edit_page($page) { + ctools_include('form'); + drupal_set_title($page->subtask['admin title']); + // Provide and process the save page form before anything else. + $form_state = array('page' => &$page); + $form = ctools_build_form('page_manager_save_page_form', $form_state); + + $operations = page_manager_get_operations($page); + $args = array('summary'); + $rendered_operations = page_manager_render_operations($page, $operations, $args, array('class' => 'operations-main'), 'nav'); + $content = page_manager_get_operation_content(FALSE, $page, $args, $operations); + + $output = theme('page_manager_edit_page', $page, $form, $rendered_operations, $content); + return $output; +} + +/** + * Entry point to edit a single operation for a page. + * + * @param $js + * Whether or not the page was called via javascript. + * @param $page + * The cached page that is being edited. + * @param ... + * A number of items used to drill down into the actual operation called. + */ +function page_manager_edit_page_operation() { + $args = func_get_args(); + $js = array_shift($args); + $page = array_shift($args); + + $operations = page_manager_get_operations($page); + $content = page_manager_get_operation_content($js, $page, $args, $operations); + + // If the operation requested we go somewhere else afterward, oblige it. + if (isset($content['new trail'])) { + $args = $content['new trail']; + // Get operations again, for the operation may have changed their availability. + $operations = page_manager_get_operations($page); + $content = page_manager_get_operation_content($js, $page, $args, $operations); + } + + // Rendering the content may have been a form submission that changed the + // operations, such as renaming or adding a handler. Thus we get a new set + // of operations. + $operations = page_manager_get_operations($page); + $rendered_operations = page_manager_render_operations($page, $operations, $args, array('class' => 'operations-main'), 'nav'); + + // Since this form should never be submitted to this page, process it late so + // that we can be sure it notices changes. + ctools_include('form'); + $form_state = array('page' => &$page); + $form = ctools_build_form('page_manager_save_page_form', $form_state); + + $output = theme('page_manager_edit_page', $page, $form, $rendered_operations, $content); + + if ($js) { + $commands = array(); + if (isset($content['js settings'])) { + $commands[] = ctools_ajax_command_settings($content['js settings']); + } + $commands[] = ctools_ajax_command_replace('#page-manager-edit', $output); + + ctools_ajax_render($commands); + } + + drupal_set_title($page->subtask['admin title']); + return $output; +} + +/** + * Take the operations array from a task and expand it. + * + * This allows some of the operations to be dynamic, based upon settings + * on the task or the task's handlers. Each operation should have a type. In + * addition to all the types allowed in page_manager_render_operations, these + * types will be dynamically replaced with something else: + * - 'handlers': An automatically created group that contains all the task's + * handlers and appropriate links. + * - 'function': A callback (which will be placed in the 'function' parameter + * that should return an array of operations. This can be used to provide + * additional, dynamic links if needed. + */ +function page_manager_get_operations($page, $operations = NULL) { + if (!isset($operations)) { + // All tasks have at least these 2 ops: + $operations = array( + 'summary' => array( + 'title' => t('Summary'), + 'description' => t('Get a summary of the information about this page.'), + 'path' => 'admin/build/pages/edit', + 'ajax' => FALSE, + 'no operations' => TRUE, + 'form info' => array( + 'no buttons' => TRUE, + ), + 'form' => 'page_manager_page_summary', + ), + 'actions' => array( + 'type' => 'group', + 'title' => '', + 'class' => 'operations-actions', + 'location' => 'primary', + 'children' => array(), + ), + ); + + if (isset($page->subtask['operations'])) { + $operations += $page->subtask['operations']; + // add actions separately. + if (!empty($page->subtask['operations']['actions'])) { + $operations['actions']['children'] += $page->subtask['operations']['actions']['children']; + } + } + $operations['handlers'] = array('type' => 'handlers'); + } + + $result = array(); + foreach ($operations as $id => $operation) { + if (empty($operation['type'])) { + $operation['type'] = 'operation'; + } + switch ($operation['type']) { + case 'handlers': + $result[$id] = page_manager_get_handler_operations($page); + break; + case 'function': + if (function_exists($operation['function'])) { + $retval = $function($page, $operation); + if (is_array($retval)) { + $result[$id] = $retval; + } + } + break; + default: + $result[$id] = $operation; + } + } + + if (!empty($page->subtask['enable callback']) && !empty($page->subtask['disabled']) && empty($result['actions']['children']['enable'])) { + $result['actions']['children']['enable'] = array( + 'title' => t('Enable'), + 'description' => t('Activate this page so that it will be in use in your system.'), + 'form' => 'page_manager_enable_form', + 'ajax' => FALSE, + 'silent' => TRUE, + 'no update and save' => TRUE, + 'form info' => array( + 'finish text' => t('Enable'), + ), + ); + } + + if (!empty($page->subtask['enable callback']) && empty($page->subtask['disabled']) && empty($result['actions']['children']['disable'])) { + $result['actions']['children']['disable'] = array( + 'title' => t('Disable'), + 'description' => t('De-activate this page. The data will remain but the page will not be in use on your system.'), + 'form' => 'page_manager_disable_form', + 'ajax' => FALSE, + 'silent' => TRUE, + 'no update and save' => TRUE, + 'form info' => array( + 'finish text' => t('Disable'), + ), + ); + } + + $result['actions']['children']['add'] = array( + 'title' => t('Add variant'), + 'description' => t('Add a new variant to this page.'), + 'form' => 'page_manager_handler_add', + 'ajax' => FALSE, + 'silent' => TRUE, // prevents a message about updating and prevents this item from showing as changed. + 'no update and save' => TRUE, // get rid of update and save button which is bad here. + 'form info' => array( + 'finish text' => t('Create variant'), + ), + ); + + // Restrict variant import to users who can already execute arbitrary PHP + if (user_access('use PHP for block visibility')) { + $result['actions']['children']['import'] = array( + 'title' => t('Import variant'), + 'description' => t('Add a new variant to this page from code exported from another page.'), + 'form' => 'page_manager_handler_import', + ); + } + + if (count($page->handlers) > 1) { + $result['actions']['children']['rearrange'] = array( + 'title' => t('Reorder variants'), + 'ajax' => FALSE, + 'description' => t('Change the priority of the variants to ensure that the right one gets selected.'), + 'form' => 'page_manager_handler_rearrange', + ); + } + + // This is a special operation used to configure a new task handler before + // it is added. + if (isset($page->new_handler)) { + $plugin = page_manager_get_task_handler($page->new_handler->handler); + $result['actions']['children']['configure'] = array( + 'title' => t('Configure'), + 'description' => t('Configure a newly created variant prior to actually adding it to the page.'), + 'ajax' => FALSE, + 'no update and save' => TRUE, // get rid of update and save button which is bad here. + 'form info' => array( + // We use our own cancel and finish callback to handle the fun stuff. + 'finish callback' => 'page_manager_handler_add_finish', + 'cancel callback' => 'page_manager_handler_add_cancel', + 'show trail' => TRUE, + 'show back' => TRUE, + 'finish text' => t('Create variant'), + ), + 'form' => array( + 'forms' => $plugin['forms'], + ), + ); + + foreach ($page->forms as $id) { + if (isset($plugin['add features'][$id])) { + $result['actions']['children']['configure']['form']['order'][$id] = $plugin['add features'][$id]; + } + else if (isset($plugin['required forms'][$id])) { + $result['actions']['children']['configure']['form']['order'][$id] = $plugin['required forms'][$id]; + } + } + } + + if ($page->locked) { + $result['actions']['children']['break-lock'] = array( + 'title' => t('Break lock'), + 'description' => t('Break the lock on this page so that you can edit it.'), + 'form' => 'page_manager_break_lock', + 'ajax' => FALSE, + 'no update and save' => TRUE, // get rid of update and save button which is bad here. + 'form info' => array( + 'finish text' => t('Break lock'), + ), + 'even locked' => TRUE, // show button even if locked + 'silent' => TRUE, + ); + } + + drupal_alter('page_manager_operations', $result, $page); + return $result; +} + +/** + * Collect all the operations related to task handlers (variants) and + * build a menu. + */ +function page_manager_get_handler_operations(&$page) { + ctools_include('export'); + $group = array( + 'type' => 'group', + 'class' => 'operations-handlers', + 'title' => t('Variants'), + ); + + $operations = array(); + + // If there is only one variant, let's not have it collapsible. + $collapsible = count($page->handler_info) != 1; + foreach ($page->handler_info as $id => $info) { + if ($info['changed'] & PAGE_MANAGER_CHANGED_DELETED) { + continue; + } + $handler = $page->handlers[$id]; + $plugin = page_manager_get_task_handler($handler->handler); + + $operations[$id] = array( + 'type' => 'group', + 'class' => 'operations-handlers-' . $id, + 'title' => page_manager_get_handler_title($plugin, $handler, $page->task, $page->subtask_id), + 'collapsible' => $collapsible, + 'children' => array(), + ); + + $operations[$id]['children']['actions'] = array( + 'type' => 'group', + 'class' => 'operations-handlers-actions-' . $id, + 'title' => t('Variant operations'), + 'children' => array(), + 'location' => $id, + ); + + // There needs to be a 'summary' item here for variants. + $operations[$id]['children']['summary'] = array( + 'title' => t('Summary'), + 'description' => t('Get a summary of the information about this variant.'), + 'form info' => array( + 'no buttons' => TRUE, + ), + 'form' => 'page_manager_handler_summary', + ); + + if ($plugin && isset($plugin['operations'])) { + $operations[$id]['children'] += $plugin['operations']; + } + + $actions = &$operations[$id]['children']['actions']['children']; + + $actions['clone'] = array( + 'title' => t('Clone'), + 'description' => t('Make an exact copy of this variant.'), + 'form' => 'page_manager_handler_clone', + ); + $actions['export'] = array( + 'title' => t('Export'), + 'description' => t('Export this variant into code to import into another page.'), + 'form' => 'page_manager_handler_export', + ); + if ($handler->export_type == (EXPORT_IN_CODE | EXPORT_IN_DATABASE)) { + $actions['delete'] = array( + 'title' => t('Revert'), + 'description' => t('Remove all changes to this variant and revert to the version in code.'), + 'form' => 'page_manager_handler_delete', + 'no update and save' => TRUE, + 'form info' => array( + 'finish text' => t('Revert'), + ), + ); + } + else if ($handler->export_type != EXPORT_IN_CODE) { + $actions['delete'] = array( + 'title' => t('Delete'), + 'description' => t('Remove this variant from the page completely.'), + 'form' => 'page_manager_handler_delete', + 'form info' => array( + 'finish text' => t('Delete'), + 'save text' => t('Delete and save'), + ), + ); + } + if (!empty($handler->disabled)) { + $actions['enable'] = array( + 'title' => t('Enable'), + 'description' => t('Activate this variant so that it will be in use in your system.'), + 'form' => 'page_manager_handler_enable', + 'silent' => TRUE, + 'form info' => array( + 'finish text' => t('Enable'), + 'save text' => t('Enable and save'), + ), + ); + } + else { + $actions['disable'] = array( + 'title' => t('Disable'), + 'description' => t('De-activate this variant. The data will remain but the variant will not be in use on your system.'), + 'form' => 'page_manager_handler_disable', + 'silent' => TRUE, + 'form info' => array( + 'finish text' => t('Disable'), + 'save text' => t('Disable and save'), + ), + ); + } + + drupal_alter('page_manager_variant_operations', $operations[$id], $handler); + } + if (empty($operations)) { + $operations['empty'] = array( + 'type' => 'text', + 'title' => t('No variants'), + ); + } + + $group['children'] = $operations; + return $group; +} + +/** + * Get an operation from a trail. + * + * @return array($operation, $active, $args) + */ +function page_manager_get_operation($operations, $trail) { + $args = $trail; + $stop = FALSE; + $active = array(); + $titles = array(); + // Drill down into operations array: + while (!$stop) { + $check = reset($args); + $stop = TRUE; + if (is_array($operations)) { + if (isset($operations[$check])) { + $active[] = $check; + $operation = array_shift($args); + // check to see if this operation has children. If so, we continue. + if (!isset($operations[$check]['children'])) { + $operations = $operations[$check]; + } + else { + $titles[] = $operations[$check]['title']; + $operations = $operations[$check]['children']; + // continue only if the operation hs children. + $stop = FALSE; + } + } + } + } + + return array($operations, $active, $args, $titles); +} + +/** + * Fetch the content for an operation. + * + * First, this drills down through the arguments to find the operation, and + * turns whatever it finds into the active trail which is then used to + * hilite where we are when rendering the operation list. + * + * The arguments are discovered from the URL, and are an exact match for where + * the operation is in the hierarchy. For example, handlers/foo/settings will + * be the operation to edit the settings for the handler named foo. This comes + * in as an array ('handlers', 'foo', 'settings') and is used to find where the + * data for that operation is in the array. + */ +function page_manager_get_operation_content($js, &$page, $trail, $operations) { + list($operation, $active, $args, $titles) = page_manager_get_operation($operations, $trail); + // Once we've found the operation, send it off to render. + if ($operation) { + $content = _page_manager_get_operation_content($js, $page, $active, $operation, $titles, $args); + } + + if (empty($content)) { + $content = _page_manager_get_operation_content($js, $page, array('summary'), $operations['summary']); + } + + return $content; +} + +/** + * Fetch the content for an operation, after it's been discovered from arguments. + * + * This system runs through the CTools form wizard. Each operation specifies a form + * or set of forms that it may use. Operations may also specify wrappers and can + * set their own next/finish handlers so that they can make additional things happen + * at the end. + */ +function _page_manager_get_operation_content($js, &$page, $active, $operation, $titles = array(), $args = array()) { + if (isset($operation['form'])) { + $form_info = array( + 'id' => 'page_manager_page', + 'finish text' => t('Update'), + 'show trail' => FALSE, + 'show back' => FALSE, + 'show return' => FALSE, + 'show cancel' => FALSE, + 'next callback' => 'page_manager_edit_page_next', + 'finish callback' => 'page_manager_edit_page_finish', + // Items specific to the 'edit' routines that will get moved over: + 'path' => page_manager_edit_url($page->task_name, $active) . "/%step", + // wrapper function to add an extra finish button. + 'wrapper' => 'page_manager_operation_wrapper', + ); + + // If $operation['form'] is simply a string, then it is the function + // name of the form. + if (!is_array($operation['form'])) { + $form_info['order'] = array( + 'form' => $operation['title'], + ); + $form_info['forms'] = array( + 'form' => array('form id' => $operation['form']), + ); + if (isset($operation['wrapper'])) { + $form_info['forms']['form']['wrapper'] = $operation['wrapper']; + } + } + // Otherwise it's the order and forms arrays directly. + else { + $form_info['order'] = $operation['form']['order']; + $form_info['forms'] = $operation['form']['forms']; + } + + // Allow the operation to override any form info settings: + if (isset($operation['form info'])) { + foreach ($operation['form info'] as $key => $setting) { + $form_info[$key] = $setting; + } + } + + if (!empty($page->subtask['operations include'])) { + // Quickly load any files necessary to display the forms. + $page->subtask['operations include']['function'] = 'nop'; + ctools_plugin_get_function($page->subtask, 'operations include'); + } + + $step = array_shift($args); + // If step is unset, go with the basic step. + if (!isset($step)) { + $step = current(array_keys($form_info['order'])); + } + + // If it is locked, hide the buttonzzz! + if ($page->locked && empty($operation['even locked'])) { + $form_info['no buttons'] = TRUE; + } + + ctools_include('wizard'); + $form_state = array( + 'page' => $page, + 'type' => 'edit', + 'ajax' => $js && (!isset($operation['ajax']) || !empty($operation['ajax'])), + 'rerender' => TRUE, + 'trail' => $active, + 'task_name' => $page->task_name, + 'task_id' => $page->task_id, + 'task' => $page->task, + 'subtask_id' => $page->subtask_id, + 'subtask' => $page->subtask, + 'operation' => $operation, + ); + + if ($active && $active[0] == 'handlers' && isset($form_state['page']->handlers[$form_state['trail'][1]])) { + $form_state['handler_id'] = $form_state['trail'][1]; + $form_state['handler'] = &$form_state['page']->handlers[$form_state['handler_id']]; + } + + if ($active && $active[0] == 'actions' && $active[1] == 'configure' && isset($form_state['page']->new_handler)) { + $form_state['handler_id'] = $form_state['page']->new_handler->name; + $form_state['handler'] = &$form_state['page']->new_handler; + } + + $output = ctools_wizard_multistep_form($form_info, $step, $form_state); + $title = empty($form_state['title']) ? $operation['title'] : $form_state['title']; + $titles[] = $title; + $title = implode(' » ', array_filter($titles)); + if (isset($form_state['js settings'])) { + $js_settings = $form_state['js settings']; + } + + // If there are messages for the form, render them. + if ($messages = theme('status_messages')) { + $output = $messages . $output; + } + + $description = isset($operation['admin description']) ? $operation['admin description'] : (isset($operation['description']) ? $operation['description'] : ''); + $return = array( + 'title' => $title, + 'content' => $output, + 'description' => $description, + ); + + // Append any extra content, used for the preview which is submitted then + // rendered. + if (isset($form_state['content'])) { + $return['content'] .= $form_state['content']; + } + + // If the form wanted us to go somewhere else next, pass that along. + if (isset($form_state['new trail'])) { + $return['new trail'] = $form_state['new trail']; + } + } + else { + $return = array( + 'title' => t('Error'), + 'content' => t('This operation trail does not exist.'), + ); + } + + if (isset($js_settings)) { + $return['js settings'] = $js_settings; + } + + $return['active'] = $active; + return $return; +} + +function page_manager_operation_wrapper(&$form, &$form_state) { + if (empty($form_state['operation']['no update and save']) && !empty($form['buttons']['return']['#wizard type']) && $form['buttons']['return']['#wizard type']) { + $form['buttons']['save'] = array( + '#type' => 'submit', + '#value' => !empty($form_state['form_info']['save text']) ? $form_state['form_info']['save text'] : t('Update and save'), + '#wizard type' => 'finish', + '#attributes' => $form['buttons']['return']['#attributes'], + '#save' => TRUE, + ); + } +} + +/** + * Callback generated when the an operation edit finished. + */ +function page_manager_edit_page_finish(&$form_state) { + if (empty($form_state['operation']['silent'])) { + if (empty($form_state['clicked_button']['#save'])) { + drupal_set_message(t('The page has been updated. Changes will not be permanent until you save.')); + } + else { + drupal_set_message(t('The page has been updated and saved.')); + } + $path = array(); + foreach ($form_state['trail'] as $operation) { + $path[] = $operation; + $form_state['page']->changes[implode('/', $path)] = TRUE; + } + } + + // If a handler was modified, set it to changed so we know to overwrite it. + if (isset($form_state['handler_id'])) { + $form_state['page']->handler_info[$form_state['handler_id']]['changed'] |= PAGE_MANAGER_CHANGED_CACHED; + } + + // While we make buttons go away on locked pages, it is still possible to + // have a lock a appear while you were editing, and have your changes + // disappear. This at least warns the user that this has happened. + if (!empty($page->locked)) { + drupal_set_message(t('Unable to update changes due to lock.')); + } + + // If the 'Update and Save' button was selected, write our cache out. + if (!empty($form_state['clicked_button']['#save'])) { + page_manager_save_page_cache($form_state['page']); + page_manager_clear_page_cache($form_state['page']->task_name); + $form_state['page'] = page_manager_get_page_cache($form_state['page']->task_name); + } + else { + if (empty($form_state['do not cache'])) { + page_manager_set_page_cache($form_state['page']); + } + } + + // We basically always want to force a rerender when the forms + // are finished, so make sure there is a new trail. + if (empty($form_state['new trail'])) { + // force a rerender to get rid of old form items that may have changed + // during save. + $form_state['new trail'] = $form_state['trail']; + } + + if (isset($form_state['new trail']) && empty($form_state['ajax'])) { + $form_state['redirect'] = page_manager_edit_url($form_state['page']->task_name, $form_state['new trail']); + } + + $form_state['complete'] = TRUE; +} + +/** + * Callback generated when the 'next' button is clicked. + * + * All we do here is store the cache. + */ +function page_manager_edit_page_next(&$form_state) { + page_manager_set_page_cache($form_state['page']); +} + +/** + * Callback generated when the 'cancel' button is clicked. + * + * All we do here is clear the cache. + */ +function page_manager_edit_page_cancel(&$form_state) { + $page = $form_state['page']; +} + +/** + * Render an operations array. + * + * This renders an array of operations into a series of nested UL statements, + * with ajax automatically on unless specified otherwise. Operations will + * automatically have the URLs generated nested. + * + * Each operation should have a 'type', which tells the renderer how to deal + * with it: + * - 'operation': An AJAX link to render. This is the default and is + * assumed if a type is not specified. Other fields for the operation: + * - - 'title': The text to display. Can be an image. Must be pre-sanitized. + * - - 'description': Text to place in the hover box over the link using the + * title attribute. + * - - 'arguments': Anything optional to put at the end of the URL. + * - - 'path': If set, overrides the default path. + * - - 'no operations': If set, the path will not have operations appended. + * - - 'no task': If set, the path will not have the task id. + * - - 'no link': If set, this item will just be text, not a link. + * - - 'ajax': If set to TRUE, ajax will be used. The default is TRUE. + * - - 'class': An optional class to specify for the link. + * - - 'form': The form to display for this operation, if using a single form. + * - - 'forms': An array of forms that must be paired with 'order' of this + * operation uses multiple forms. See wizard tool for details. + * - - 'order': The form order to use for multiple forms. See wizard tool for + * details. + * - - 'form info': Form info overrides for the wizard. See the wizard tool + * for available settings + * - 'group': + * - - 'title': The title of the link. May be HTML. + * - - 'title class': A class to apply to the title. + * - - 'children': An array of more operations that this group represents. + * All operations within this group will have this group's ID as part + * of the AJAX url to make it easier to find. + * - - 'class': A class to apply to the UL of the children. + * - - 'collapsible': If TRUE the collapsible tool will be used. + */ +function page_manager_render_operations(&$page, $operations, $active_trail, $attributes, $location, $parents = array()) { + if (!isset($output[$location])) { + $output[$location] = ''; + } + + $keys = array_keys($operations); + $first = array_shift($keys); + $last = array_pop($keys); + + // Make sure the 'first' and 'last' operations are part of THIS nav tree: + while ($keys && isset($operations[$first]['location']) && $operations[$first]['location'] != $location) { + $first = array_shift($keys); + } + while ($keys && isset($operations[$last]['location']) && $operations[$last]['location'] != $location) { + $last = array_pop($keys); + } + + $active = reset($active_trail); + foreach ($operations as $id => $operation) { + $current_path = ''; + if ($parents) { + $current_path .= implode('/', $parents) . '/'; + } + $current_path .= $id; + + if (empty($operation['type'])) { + $operation['type'] = 'operation'; + } + + // We only render an li for things in the same nav tree. + if (empty($operation['location']) || $operation['location'] == $location) { + $class = $attributes['class']; + if ($id == $first) { + $class .= ' operation-first'; + } + else if ($id == $last) { + $class .= ' operation-last'; + } + + if (empty($operation['silent']) && !empty($page->changes[$current_path])) { + $class .= $operation['type'] == 'group' ? ' changed-group' : ' changed'; + } + else { + $class .= ' not-changed'; + } + + if ($active == $id) { + $class .= $operation['type'] == 'group' ? ' active-group' : ' active'; + } + else { + $class .= ' not-active'; + } + + $output[$location] .= '<li class="' . $class . '">'; + } + + switch ($operation['type']) { + case 'text': + $output[$location] .= $operation['title']; + break; + case 'operation': + $path = isset($operation['path']) ? $operation['path'] : 'admin/build/pages/nojs/operation'; + if (!isset($operation['no task'])) { + $path .= '/' . $page->task_name; + } + + if (!isset($operation['no operations'])) { + $path .= '/' . $current_path; + if (isset($operation['arguments'])) { + $path .= '/' . $arguments; + } + } + + $class = 'page-manager-operation'; + if (!isset($operation['ajax']) || !empty($operation['ajax'])) { + $class .= ' ctools-use-ajax'; + } + if (!empty($operation['class'])) { + $class .= ' ' . $operation['class']; + } + + $description = isset($operation['description']) ? $operation['description'] : ''; + if (empty($operation['silent']) && !empty($page->changes[$current_path])) { + $description .= ' ' . t('This setting contains unsaved changes.'); + } + + $output[$location] .= l($operation['title'], $path, array('attributes' => array('id' => 'page-manager-operation-' . $id, 'class' => $class, 'title' => $description), 'html' => TRUE)); + break; + case 'group': + if ($active == $id) { + $trail = $active_trail; + array_shift($trail); + } + else { + $trail = array(); + } + $group_location = isset($operation['location']) ? $operation['location'] : $location; + $temp = page_manager_render_operations($page, $operation['children'], $trail, $operation, $group_location, array_merge($parents, array($id))); + if ($temp) { + foreach ($temp as $id => $text) { + if (empty($output[$id])) { + $output[$id] = ''; + } + $output[$id] .= $text; + } + } + break; + } + + if (empty($operation['location']) || $operation['location'] == $location) { + $output[$location] .= '</li>'; + } + } + + if ($output[$location]) { + $output[$location] = '<ul class="page-manager-operations ' . $attributes['class'] . '">' . $output[$location] . '</ul>'; + + if (!empty($attributes['title'])) { + $class = ''; + if (isset($attributes['title class'])) { + $class = $attributes['title class']; + } + $title = '<div class="page-manager-group-title' . $class . '">' . $attributes['title'] . '</div>'; + + if (!empty($attributes['collapsible'])) { + $output[$location] = theme('ctools_collapsible', $title, $output[$location], empty($active_trail)); + } + else { + $output[$location] = $title . $output[$location]; + } + } + return $output; + } +} + +/** + * Provide a simple form for saving the page manager info out of the cache. + */ +function page_manager_save_page_form(&$form_state) { + if (!empty($form_state['page']->changed)) { + $form['markup'] = array( + '#value' => '<div class="changed-notification">' . t('You have unsaved changes to this page. You must select Save to write them to the database, or Cancel to discard these changes. Please note that if you have changed any form, you must submit that form before saving.') . '</div>', + ); + + // Always make sure we submit back to the proper page. + $form['#action'] = url('admin/build/pages/edit/' . $form_state['page']->task_name); + $form['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + '#submit' => array('page_manager_save_page_form_submit'), + ); + + $form['cancel'] = array( + '#type' => 'submit', + '#value' => t('Cancel'), + '#submit' => array('page_manager_save_page_form_cancel'), + ); + return $form; + } +} + +/** + * Save the page. + */ +function page_manager_save_page_form_submit(&$form, &$form_state) { + page_manager_save_page_cache($form_state['page']); +} + +/** + * Discard changes to the page. + */ +function page_manager_save_page_form_cancel(&$form, &$form_state) { + drupal_set_message(t('All pending changes have been discarded, and the page is now unlocked.')); + page_manager_clear_page_cache($form_state['page']->task_name); + + if (!empty($form_state['page']->new)) { + $form_state['redirect'] = 'admin/build/pages'; + } +} + +// -------------------------------------------------------------------------- +// Handler (variant) related forms. + +/** + * Add a new task handler. + */ +function page_manager_handler_add(&$form, &$form_state) { + // Get a list of possible task handlers for this task. + page_manager_handler_add_form($form, $form_state); +} + +/** + * Handler related forms. + */ +function page_manager_handler_add_submit(&$form, &$form_state) { + $cache = $form_state['page']; + $plugin = page_manager_get_task_handler($form_state['values']['handler']); + + // Create a new handler. + $handler = page_manager_new_task_handler($plugin); + if (!empty($form_state['values']['title'])) { + $handler->conf['title'] = $form_state['values']['title']; + } + else { + $handler->conf['title'] = $plugin['title']; + } + $cache->new_handler = $handler; + + // Figure out which forms to present them with + $cache->forms = array(); + + $features = $form_state['values']['features']; + if (isset($features[$form_state['values']['handler']])) { + $cache->forms = array_merge($cache->forms, array_keys(array_filter($features[$form_state['values']['handler']]))); + } + + if (isset($plugin['required forms'])) { + $cache->forms = array_merge($cache->forms, array_keys($plugin['required forms'])); + } + + $form_state['no_rerender'] = TRUE; + if (!empty($cache->forms)) { + // Tell the form to go to the config page. + drupal_set_message(t('Before this variant can be added, it must be configured. When you are finished, click "Create variant" at the end of this wizard to add this to your page.')); + $form_state['new trail'] = array('actions', 'configure'); + } + else { + // It has no forms at all. Add the variant and go to its first operation. + page_manager_handler_add_finish($form_state); + } +} + +/** + * Finish the add process and make the new handler official. + */ +function page_manager_handler_add_finish(&$form_state) { + $page = &$form_state['page']; + $handler = $page->new_handler; + page_manager_handler_add_to_page($page, $handler); + + // Remove the temporary page. + unset($page->new_handler); + unset($page->forms); + + // Set the new destination + $plugin = page_manager_get_task_handler($handler->handler); + if (!empty($plugin['add finish'])) { + $location = $plugin['add finish']; + } + else { + $keys = array_keys($plugin['operations']); + $location = reset($keys); + } + + $form_state['new trail'] = array('handlers', $handler->name, $location); + + // Pass through. + page_manager_edit_page_finish($form_state); +} + +/** + * Throw away a new handler and return to the add form + */ +function page_manager_handler_add_cancel(&$form_state) { + $form_state['new trail'] = array('handlers', 'add'); + + // Remove the temporary page. + unset($page->new_handler); + unset($page->forms); +} + +/** + * Provide a consistent UI for adding handlers. + */ +function page_manager_handler_add_form(&$form, $form_state, $features = array()) { + $task = $form_state['task']; + $task_handler_plugins = page_manager_get_task_handler_plugins($task); + if (empty($task_handler_plugins)) { + drupal_set_message(t('There are currently no variants available and a page may not be added. Perhaps you need to install the Panels module to get a variant?'), 'error'); + $form['buttons']['return']['#disabled'] = TRUE; + return; + } + + foreach ($task_handler_plugins as $id => $plugin) { + $options[$id] = $plugin['title']; + if (isset($plugin['add features'])) { + $features[$id] = $plugin['add features']; + } + } + + if (!isset($form_state['type']) || $form_state['type'] != 'add') { + $form['title'] = array( + '#type' => 'textfield', + '#title' => t('Title'), + '#description' => t('Administrative title of this variant. If you leave blank it will be automatically assigned.'), + ); + } + + $form['handler'] = array( + '#title' => t('Variant type'), + '#type' => 'select', + '#options' => $options, + ); + + // This set of checkboxes is not dangerous at all. + $form['features'] = array( + '#type' => 'checkboxes', + '#validated' => TRUE, + '#title' => t('Optional features'), + '#options' => array(), + '#description' => t('Check any optional features you need to be presented with forms for configuring them. If you do not check them here you will still be able to utilize these features once the new page is created. If you are not sure, leave these unchecked.'), + '#tree' => TRUE, + ); + + ctools_include('dependent'); + foreach ($features as $plugin => $feature_list) { + foreach ($feature_list as $feature_id => $feature) { + $form['features'][$plugin][$feature_id] = array( + '#type' => 'checkbox', + '#title' => $feature, + ); + if (!empty($form_state['page']->forms) && in_array($feature_id, $form_state['page']->forms)) { + $form['features'][$plugin][$feature_id]['#default_value'] = TRUE; + } + + if ($plugin != 'default') { + $form['features'][$plugin][$feature_id] += array( + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-handler' => array($plugin)), + ); + } + } + } +} + +/** + * Rearrange the order of variants. + */ +function page_manager_handler_import(&$form, &$form_state) { + $form['title'] = array( + '#type' => 'textfield', + '#title' => t('Variant name'), + '#description' => t('Enter the name of the new variant.'), + ); + + if (user_access('use PHP for block visibility')) { + $form['object'] = array( + '#type' => 'textarea', + '#title' => t('Paste variant code here'), + '#rows' => 15, + ); + } + // Users ordinarily can't get here without the PHP block visibility perm. + // In case they somehow do, though, disable the form widget for extra safety. + else { + $form['shoveoff'] = array( + '#value' => '<div>' . t('You do not have sufficient permissions to perform this action.') . '</div>', + ); + } +} + +/** + * Make sure that an import actually provides a handler. + */ +function page_manager_handler_import_validate($form, &$form_state) { + if (!user_access('use PHP for block visibility')) { + form_error($form['shoveoff'], t('You account permissions do not permit you to import.')); + return; + } + ob_start(); + eval($form_state['values']['object']); + ob_end_clean(); + + if (empty($handler)) { + $errors = ob_get_contents(); + if (empty($errors)) { + $errors = t('No variant found.'); + } + + form_error($form['object'], t('Unable to get a variant from the import. Errors reported: @errors', array('@errors' => $errors))); + } + + $form_state['handler'] = $handler; +} + +/** + * Clone an existing task handler into a new handler. + */ +function page_manager_handler_import_submit($form, &$form_state) { + $handler = $form_state['handler']; + + page_manager_handler_add_to_page($form_state['page'], $handler, $form_state['values']['title']); + + $plugin = page_manager_get_task_handler($handler->handler); + // It has no forms at all. Add the variant and go to its first operation. + $keys = array_keys($plugin['operations']); + $form_state['new trail'] = array('handlers', $handler->name, reset($keys)); +} + +/** + * Rearrange the order of variants. + */ +function page_manager_handler_rearrange(&$form, &$form_state) { + $page = $form_state['page']; + + $form['handlers'] = array('#tree' => TRUE); + + foreach ($page->handler_info as $id => $info) { + if ($info['changed'] & PAGE_MANAGER_CHANGED_DELETED) { + continue; + } + $handler = $page->handlers[$id]; + $plugin = page_manager_get_task_handler($handler->handler); + + $form['handlers'][$id]['title'] = array( + '#value' => page_manager_get_handler_title($plugin, $handler, $page->task, $page->subtask_id), + ); + + $form['handlers'][$id]['weight'] = array( + '#type' => 'weight', + '#default_value' => $info['weight'], + '#delta' => 30, + ); + } +} + +function page_manager_handler_rearrange_submit(&$form, &$form_state) { + $handler_info = &$form_state['page']->handler_info; + + foreach ($form_state['values']['handlers'] as $id => $info) { + if ($handler_info[$id]['weight'] = $info['weight']) { + $handler_info[$id]['weight'] = $info['weight']; + $handler_info[$id]['changed'] |= PAGE_MANAGER_CHANGED_MOVED; + } + } + + // Sort the new cache. + uasort($handler_info, '_page_manager_handler_sort'); + +} + +/** + * Used as a callback to uasort to sort the task cache by weight. + * + * The 'name' field is used as a backup when weights are the same, which + * can happen when multiple modules put items out there at the same + * weight. + */ +function _page_manager_handler_sort($a, $b) { + if ($a['weight'] < $b['weight']) { + return -1; + } + elseif ($a['weight'] > $b['weight']) { + return 1; + } + elseif ($a['name'] < $b['name']) { + return -1; + } + elseif ($a['name'] > $b['name']) { + return 1; + } +} + +/** + * Rearrange the order of variants. + */ +function page_manager_handler_delete(&$form, &$form_state) { + if ($form_state['handler']->type == t('Overridden')) { + $text = t('Reverting the variant will delete the variant that is in the database, reverting it to the original default variant. This deletion will not be made permanent until you click Save.'); + } + else { + $text = t('Are you sure you want to delete this variant? This deletion will not be made permanent until you click Save.'); + } + $form['markup'] = array( + '#value' => '<p>' . $text . '</p>', + ); + +} + +/** + * Submit handler to delete a view. + */ +function page_manager_handler_delete_submit(&$form, &$form_state) { + $form_state['page']->handler_info[$form_state['handler_id']]['changed'] |= PAGE_MANAGER_CHANGED_DELETED; + $form_state['new trail'] = array('summary'); +} + +/** + * Entry point to export a page. + */ +function page_manager_handler_export(&$form, &$form_state) { + $export = page_manager_export_task_handler($form_state['handler']); + + $lines = substr_count($export, "\n"); + $form['code'] = array( + '#type' => 'textarea', + '#default_value' => $export, + '#rows' => $lines, + ); + + unset($form['buttons']); +} + +/** + * Rearrange the order of variants. + */ +function page_manager_handler_clone(&$form, &$form_state) { + // This provides its own button because it does something totally different. + $form['title'] = array( + '#type' => 'textfield', + '#title' => t('Variant name'), + '#description' => t('Enter the name of the new variant.'), + ); +} + +/** + * Clone an existing task handler into a new handler. + */ +function page_manager_handler_clone_submit($form, &$form_state) { + $export = page_manager_export_task_handler($form_state['handler']); + ob_start(); + eval($export); + ob_end_clean(); + + page_manager_handler_add_to_page($form_state['page'], $handler, $form_state['values']['title']); + + $plugin = page_manager_get_task_handler($handler->handler); + // It has no forms at all. Add the variant and go to its first operation. + $keys = array_keys($plugin['operations']); + $form_state['new trail'] = array('handlers', $handler->name, reset($keys)); +} + +/** + * Form to enable a handler. + */ +function page_manager_handler_enable(&$form, &$form_state) { + $form['markup'] = array( + '#value' => t('This variant is currently disabled. Enabling it will make it available in your system. This will not take effect until you save this page.'), + ); +} + +/** + * Enable the page after it has been confirmed. + */ +function page_manager_handler_enable_submit(&$form, &$form_state) { + $form_state['handler']->disabled = FALSE; + $form_state['page']->handler_info[$form_state['handler_id']]['disabled'] = FALSE; + $form_state['page']->handler_info[$form_state['handler_id']]['changed'] |= PAGE_MANAGER_CHANGED_STATUS; + $form_state['new trail'] = array('handlers', $form_state['handler_id'], 'actions', 'disable'); +} + +/** + * Form to disable a page. + */ +function page_manager_handler_disable(&$form, &$form_state) { + $form['markup'] = array( + '#value' => t('This variant is currently enabled. Disabling it will make it unavailable in your system, and it will not be used. This will not take effect until you save this page.'), + ); +} + +/** + * Form to disable a page. + */ +function page_manager_handler_summary(&$form, &$form_state) { + $handler = $form_state['handler']; + $page = $form_state['page']; + $plugin = page_manager_get_task_handler($handler->handler); + + $form['markup'] = array( + '#value' => page_manager_get_handler_summary($plugin, $handler, $page, FALSE), + ); +} + +/** + * Disable the page after it has been confirmed. + */ +function page_manager_handler_disable_submit(&$form, &$form_state) { + $form_state['handler']->disabled = TRUE; + $form_state['page']->handler_info[$form_state['handler_id']]['disabled'] = TRUE; + $form_state['page']->handler_info[$form_state['handler_id']]['changed'] |= PAGE_MANAGER_CHANGED_STATUS; + $form_state['new trail'] = array('handlers', $form_state['handler_id'], 'actions', 'enable'); +} + +/** + * Break the lock on a page so that it can be edited. + */ +function page_manager_break_lock(&$form, &$form_state) { + $form['markup'] = array( + '#value' => t('Breaking the lock on this page will <strong>discard</strong> any pending changes made by the locking user. Are you REALLY sure you want to do this?') + ); +} + +/** + * Submit to break the lock on a page. + */ +function page_manager_break_lock_submit(&$form, &$form_state) { + $page = &$form_state['page']; + $form_state['page']->locked = FALSE; + ctools_object_cache_clear_all('page_manager_page', $page->task_name); + $form_state['do not cache'] = TRUE; + drupal_set_message(t('The lock has been cleared and all changes discarded. You may now make changes to this page.')); + + $form_state['new trail'] = array('summary'); +} + +/** + * Form to enable a page. + */ +function page_manager_enable_form(&$form, &$form_state) { + $form['markup'] = array( + '#value' => t('Enabling this page will immediately make it available in your system (there is no need to wait for a save.)'), + ); +} + +/** + * Enable the page after it has been confirmed. + */ +function page_manager_enable_form_submit(&$form, &$form_state) { + $page = &$form_state['page']; + if ($function = ctools_plugin_get_function($page->subtask, 'enable callback')) { + $result = $function($page, FALSE); + menu_rebuild(); + } + $form_state['new trail'] = array('actions', 'disable'); + + // We don't want to cause this to cache if it wasn't already. If it was + // cached, however, we want to update the enabled state. + if (empty($form_state['page']->changed)) { + $form_state['do not cache'] = TRUE; + } +} + +/** + * Form to disable a page. + */ +function page_manager_disable_form(&$form, &$form_state) { + $form['markup'] = array( + '#value' => t('Disabling this page will immediately make it unavailable in your system (there is no need to wait for a save.)'), + ); +} + +/** + * Disable the page after it has been confirmed. + */ +function page_manager_disable_form_submit(&$form, &$form_state) { + $page = &$form_state['page']; + if ($function = ctools_plugin_get_function($page->subtask, 'enable callback')) { + $result = $function($page, TRUE); + menu_rebuild(); + $form_state['new trail'] = array('actions', 'enable'); + + // We don't want to cause this to cache if it wasn't already. If it was + // cached, however, we want to update the enabled state. + if (empty($form_state['page']->changed)) { + $form_state['do not cache'] = TRUE; + } + } +} + +/** + * Print the summary information for a page. + */ +function page_manager_page_summary(&$form, &$form_state) { + $page = $form_state['page']; + + $output = ''; + +/* + if (isset($form_state['subtask']['admin title'])) { + $form_state['title'] = $form_state['subtask']['admin title']; + } +*/ + + if (isset($form_state['subtask']['admin description'])) { + $output .= '<div class="description">' . $form_state['subtask']['admin description'] . '</div>'; + } + + $output .= page_manager_get_page_summary($page->task, $page->subtask); + + if (!empty($page->handlers)) { + foreach ($page->handler_info as $id => $info) { + if ($info['changed'] & PAGE_MANAGER_CHANGED_DELETED) { + continue; + } + + $handler = $page->handlers[$id]; + $plugin = page_manager_get_task_handler($handler->handler); + + $output .= '<div class="handler-summary">'; + $output .= page_manager_get_handler_summary($plugin, $handler, $page); + $output .= '</div>'; + + } + } + else { + $output .= '<p>' . t('This page has no variants and thus no output of its own.') . '</p>'; + } + + $links = array( + array( + 'title' => ' » ' . t('Add a new variant'), + 'href' => page_manager_edit_url($page->task_name, array('actions', 'add')), + 'html' => TRUE, + ), + ); + + $output .= '<div class="links">' . theme('links', $links) . '</div>'; + $form['markup'] = array( + '#value' => $output, + ); +} + +/** + * Menu callback to enable or disable a page + */ +function page_manager_enable_page($disable, $js, $page) { + if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], $page->task_name)) { + return MENU_ACCESS_DENIED; + } + if ($page->locked) { + if ($disable) { + drupal_set_message(t('Unable to disable due to lock.')); + } + else { + drupal_set_message(t('Unable to enable due to lock.')); + } + } + else { + if ($function = ctools_plugin_get_function($page->subtask, 'enable callback')) { + $result = $function($page, $disable); + menu_rebuild(); + + // We want to re-cache this if it's changed so that status is properly + // updated on the changed form. + if (!empty($page->changed)) { + page_manager_set_page_cache($page); + } + } + } + + // For now $js is not actually in use on this. + drupal_goto('admin/build/pages'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.info b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.info new file mode 100644 index 0000000000000000000000000000000000000000..8a48ce7229c5fc6d4a0c7611f2e9b698b666afa6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.info @@ -0,0 +1,12 @@ +name = Page manager +description = Provides a UI and API to manage pages within the site. +core = 6.x +dependencies[] = ctools +package = Chaos tool suite + +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.install b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.install new file mode 100644 index 0000000000000000000000000000000000000000..4c0291c0dec5fb92cec2a3a939e82c276b9c7407 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.install @@ -0,0 +1,274 @@ +<?php + +/** + * @file + * Installation routines for page manager module. + */ + +/** + * Implementation of hook_schema(). + */ +function page_manager_schema() { + // This should always point to our 'current' schema. This makes it relatively easy + // to keep a record of schema as we make changes to it. + return page_manager_schema_1(); +} + +/** + * Schema version 1 for Panels in D6. + */ +function page_manager_schema_1() { + $schema = array(); + + $schema['page_manager_handlers'] = array( + 'export' => array( + 'identifier' => 'handler', + 'bulk export' => TRUE, + 'export callback' => 'page_manager_export_task_handler', + 'primary key' => 'did', + 'api' => array( + 'owner' => 'page_manager', + 'api' => 'pages_default', + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), + 'fields' => array( + 'did' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary ID field for the table. Not used for anything except internal lookups.', + 'no export' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this task handler. Used to identify it programmatically.', + ), + 'task' => array( + 'type' => 'varchar', + 'length' => '64', + 'description' => 'ID of the task this handler is for.', + ), + 'subtask' => array( + 'type' => 'varchar', + 'length' => '64', + 'description' => 'ID of the subtask this handler is for.', + 'not null' => TRUE, + 'default' => '', + ), + 'handler' => array( + 'type' => 'varchar', + 'length' => '64', + 'description' => 'ID of the task handler being used.', + ), + 'weight' => array( + 'type' => 'int', + 'description' => 'The order in which this handler appears. Lower numbers go first.', + ), + 'conf' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Serialized configuration of the handler, if needed.', + 'not null' => TRUE, + 'serialize' => TRUE, + 'object default' => array(), + ), + ), + 'primary key' => array('did'), + 'unique keys' => array( + 'name' => array('name'), + ), + 'indexes' => array('fulltask' => array('task', 'subtask', 'weight')), + ); + + $schema['page_manager_weights'] = array( + 'description' => 'Contains override weights for page_manager handlers that are in code.', + 'fields' => array( + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this task handler. Used to identify it programmatically.', + 'not null' => TRUE, + 'default' => '', + ), + 'weight' => array( + 'type' => 'int', + 'description' => 'The order in which this handler appears. Lower numbers go first.', + ), + ), + 'primary key' => array('name'), + 'indexes' => array( + 'weights' => array('name', 'weight'), + ), + ); + + $schema['page_manager_pages'] = array( + 'description' => 'Contains page subtasks for implementing pages with arbitrary tasks.', + 'export' => array( + 'identifier' => 'page', + 'bulk export' => TRUE, + 'export callback' => 'page_manager_page_export', + 'api' => array( + 'owner' => 'page_manager', + 'api' => 'pages_default', + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), + 'fields' => array( + 'pid' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary ID field for the table. Not used for anything except internal lookups.', + 'no export' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this subtask. Used to identify it programmatically.', + ), + 'task' => array( + 'type' => 'varchar', + 'length' => '64', + 'description' => 'What type of page this is, so that we can use the same mechanism for creating tighter UIs for targeted pages.', + 'default' => 'page', + ), + 'admin_title' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Human readable title for this page subtask.', + ), + 'admin_description' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Administrative description of this item.', + 'object default' => '', + ), + 'path' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'The menu path that will invoke this task.', + ), + 'access' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Access configuration for this path.', + 'not null' => TRUE, + 'serialize' => TRUE, + 'object default' => array(), + ), + 'menu' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Serialized configuration of Drupal menu visibility settings for this item.', + 'not null' => TRUE, + 'serialize' => TRUE, + 'object default' => array(), + ), + 'arguments' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Configuration of arguments for this menu item.', + 'not null' => TRUE, + 'serialize' => TRUE, + 'object default' => array(), + ), + 'conf' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Serialized configuration of the page, if needed.', + 'not null' => TRUE, + 'serialize' => TRUE, + 'object default' => array(), + ), + ), + 'primary key' => array('pid'), + 'unique keys' => array( + 'name' => array('name'), + ), + 'indexes' => array('task' => array('task')), + ); + + return $schema; +} + +/** + * Implementation of hook_install(). + */ +function page_manager_install() { + drupal_install_schema('page_manager'); + + // If we're swapping over from delegator module, take away its tables. + // Take THAT, delegator! + if (db_table_exists('{delegator_pages}')) { + db_query("INSERT INTO {page_manager_pages} (pid, name, task, admin_title, path, access, menu, arguments, conf) (SELECT pid, name, task, admin_title, path, access, menu, arguments, conf FROM {delegator_pages})"); + db_query("INSERT INTO {page_manager_handlers} (SELECT did, name, task, subtask, handler, weight, conf FROM {delegator_handlers})"); + db_query("INSERT INTO {page_manager_weights} (SELECT name, weight FROM {delegator_weights})"); + + // Update all of the 'panel_page' type pages appropriately: + $result = db_query("SELECT * FROM {page_manager_pages} WHERE task = 'panel_page'"); + while ($page = db_fetch_object($result)) { + $page->conf = unserialize($page->conf); + $handler = new stdClass(); + $handler->name = 'page_' . $page->name . '_panel_context'; + $handler->task = 'page'; + $handler->subtask = $page->name; + $handler->handler = 'panel_context'; + $handler->weight = 0; + $handler->conf = array(); + + $default_conf = array( + 'title' => t('Panel'), + 'no_blocks' => FALSE, + 'css_id' => '', + 'css' => '', + 'contexts' => array(), + 'relationships' => array(), + 'did' => NULL, + 'css_cache' => NULL, + ); + + foreach($default_conf as $key => $default) { + if (isset($page->conf[$key])) { + $handler->conf[$key] = $page->conf[$key]; + unset($page->conf[$key]); + } + else { + $handler->conf[$key] = $default; + } + } + + $handler->conf = serialize($handler->conf); + $page->conf = serialize($page->conf); + db_query("UPDATE {page_manager_pages} SET conf = '%s', task = 'page' WHERE pid = %d", $page->conf, $page->pid); + db_query("INSERT INTO {page_manager_handlers} (name, task, subtask, handler, weight, conf) VALUES ('%s', '%s', '%s', '%s', %d, '%s')", $handler->name, $handler->task, $handler->subtask, $handler->handler, $handler->weight, $handler->conf); + } + + $ret = array(); + db_drop_table($ret, 'delegator_pages'); + db_drop_table($ret, 'delegator_handlers'); + db_drop_table($ret, 'delegator_weights'); + + // And take delegator's variables: + variable_set('page_manager_term_view_type', variable_get('delegator_term_view_type', 'multiple')); + variable_del('delegator_term_view_type'); + + variable_set('page_manager_override_anyway', variable_get('delegator_override_anyway', FALSE)); + variable_del('delegator_override_anyway'); + } + + db_query("UPDATE {system} SET weight = 99 WHERE name = 'page_manager'"); +} + +/** + * Implementation of hook_uninstall(). + */ +function page_manager_uninstall() { + drupal_uninstall_schema('page_manager'); +} + +function page_manager_update_6101() { + $ret = array(); + return $ret; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.module b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.module new file mode 100644 index 0000000000000000000000000000000000000000..4ad57ef2590665e56770f834309d6eac65adf00c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/page_manager.module @@ -0,0 +1,1163 @@ +<?php + +/** + * @file + * The page manager module provides a UI and API to manage pages. + * + * It defines pages, both for system pages, overrides of system pages, and + * custom pages using Drupal's normal menu system. It allows complex + * manipulations of these pages, their content, and their hierarchy within + * the site. These pages can be exported to code for superior revision + * control. + */ + +/** + * Bit flag on the 'changed' value to tell us if an item was moved. + */ +define('PAGE_MANAGER_CHANGED_MOVED', 0x01); + +/** + * Bit flag on the 'changed' value to tell us if an item edited or added. + */ +define('PAGE_MANAGER_CHANGED_CACHED', 0x02); + +/** + * Bit flag on the 'changed' value to tell us if an item deleted. + */ +define('PAGE_MANAGER_CHANGED_DELETED', 0x04); + +/** + * Bit flag on the 'changed' value to tell us if an item has had its disabled status changed. + */ +define('PAGE_MANAGER_CHANGED_STATUS', 0x08); + +// -------------------------------------------------------------------------- +// Drupal hooks + +/** + * Implementation of hook_perm(). + */ +function page_manager_perm() { + return array('use page manager', 'administer page manager'); +} + +/** + * Implementation of hook_ctools_plugin_directory() to let the system know + * where our task and task_handler plugins are. + */ +function page_manager_ctools_plugin_directory($owner, $plugin_type) { + if ($owner == 'page_manager') { + return 'plugins/' . $plugin_type; + } +} + +/** + * Delegated implementation of hook_menu(). + */ +function page_manager_menu() { + // For some reason, some things can activate modules without satisfying + // dependencies. I don't know how, but this helps prevent things from + // whitescreening when this happens. + if (!module_exists('ctools')) { + return; + } + + $items = array(); + $base = array( + 'access arguments' => array('use page manager'), + 'file' => 'page_manager.admin.inc', + ); + + $items['admin/build/pages'] = array( + 'title' => 'Pages', + 'description' => 'Add, edit and remove overridden system pages and user defined pages from the system.', + 'page callback' => 'page_manager_list_page', + ) + $base; + + $items['admin/build/pages/list'] = array( + 'title' => 'List', + 'page callback' => 'page_manager_list_page', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ) + $base; + + $items['admin/build/pages/edit/%page_manager_cache'] = array( + 'title' => 'Edit', + 'page callback' => 'page_manager_edit_page', + 'page arguments' => array(4), + 'type' => MENU_CALLBACK, + ) + $base; + + $items['admin/build/pages/%ctools_js/operation/%page_manager_cache'] = array( + 'page callback' => 'page_manager_edit_page_operation', + 'page arguments' => array(3, 5), + 'type' => MENU_CALLBACK, + ) + $base; + + $items['admin/build/pages/%ctools_js/enable/%page_manager_cache'] = array( + 'page callback' => 'page_manager_enable_page', + 'page arguments' => array(FALSE, 3, 5), + 'type' => MENU_CALLBACK, + ) + $base; + + $items['admin/build/pages/%ctools_js/disable/%page_manager_cache'] = array( + 'page callback' => 'page_manager_enable_page', + 'page arguments' => array(TRUE, 3, 5), + 'type' => MENU_CALLBACK, + ) + $base; + + $tasks = page_manager_get_tasks(); + + // Provide menu items for each task. + foreach ($tasks as $task_id => $task) { + $handlers = page_manager_get_task_handler_plugins($task); + // Allow the task to add its own menu items. + if ($function = ctools_plugin_get_function($task, 'hook menu')) { + $function($items, $task); + } + + // And for those that provide subtasks, provide menu items for them, as well. + foreach (page_manager_get_task_subtasks($task) as $subtask_id => $subtask) { + // Allow the task to add its own menu items. + if ($function = ctools_plugin_get_function($task, 'hook menu')) { + $function($items, $subtask); + } + } + } + + return $items; +} + +/** + * Implementation of hook_menu_alter. + * + * Get a list of all tasks and delegate to them. + */ +function page_manager_menu_alter(&$items) { + // For some reason, some things can activate modules without satisfying + // dependencies. I don't know how, but this helps prevent things from + // whitescreening when this happens. + if (!module_exists('ctools')) { + return; + } + + $tasks = page_manager_get_tasks(); + + foreach ($tasks as $task) { + if ($function = ctools_plugin_get_function($task, 'hook menu alter')) { + $function($items, $task); + } + // let the subtasks alter the menu items too. + foreach (page_manager_get_task_subtasks($task) as $subtask_id => $subtask) { + if ($function = ctools_plugin_get_function($subtask, 'hook menu alter')) { + $function($items, $subtask); + } + } + } + + return $items; +} + +/* + * Implementation of hook_theme() + */ +function page_manager_theme() { + // For some reason, some things can activate modules without satisfying + // dependencies. I don't know how, but this helps prevent things from + // whitescreening when this happens. + if (!module_exists('ctools')) { + return; + } + + $base = array( + 'path' => drupal_get_path('module', 'page_manager') . '/theme', + 'file' => 'page_manager.theme.inc', + ); + + $items = array( + 'page_manager_list_pages_form' => array( + 'arguments' => array('form' => NULL), + ) + $base, + 'page_manager_handler_rearrange' => array( + 'arguments' => array('form' => NULL), + ) + $base, + 'page_manager_edit_page' => array( + 'template' => 'page-manager-edit-page', + 'arguments' => array('page' => NULL, 'save' => NULL, 'operations' => array(), 'content' => array()), + ) + $base, + 'page_manager_lock' => array( + 'arguments' => array('page' => array()), + ) + $base, + 'page_manager_changed' => array( + 'arguments' => array('text' => NULL, 'description' => NULL), + ) + $base, + ); + + // Allow task plugins to have theme registrations by passing through: + $tasks = page_manager_get_tasks(); + + // Provide menu items for each task. + foreach ($tasks as $task_id => $task) { + if ($function = ctools_plugin_get_function($task, 'hook theme')) { + $function($items, $task); + } + } + + return $items; +} + +// -------------------------------------------------------------------------- +// Page caching +// +// The page cache is used to store a page temporarily, using the ctools object +// cache. When loading from the page cache, it will either load the cached +// version, or if there is not one, load the real thing and create a cache +// object which can then be easily stored. + +/** + * Get the cached changes to a given task handler. + */ +function page_manager_get_page_cache($task_name) { + ctools_include('object-cache'); + $cache = ctools_object_cache_get('page_manager_page', $task_name); + if (!$cache) { + $cache = new stdClass(); + $cache->task_name = $task_name; + list($cache->task_id, $cache->subtask_id) = page_manager_get_task_id($cache->task_name); + + $cache->task = page_manager_get_task($cache->task_id); + if (empty($cache->task)) { + return FALSE; + } + + if ($cache->subtask_id) { + $cache->subtask = page_manager_get_task_subtask($cache->task, $cache->subtask_id); + if (empty($cache->subtask)) { + return FALSE; + } + } + else { + $cache->subtask = $cache->task; + $cache->subtask['name'] = ''; + } + + $cache->handlers = page_manager_load_sorted_handlers($cache->task, $cache->subtask_id); + $cache->handler_info = array(); + foreach ($cache->handlers as $id => $handler) { + $cache->handler_info[$id] = array( + 'weight' => $handler->weight, + 'changed' => FALSE, + 'name' => $id, + ); + } + } + else { + // ensure the task is loaded. + page_manager_get_task($cache->task_id); + } + + if ($task_name != '::new') { + $cache->locked = ctools_object_cache_test('page_manager_page', $task_name); + } + else { + $cache->locked = FALSE; + } + + return $cache; +} + +/** + * Store changes to a task handler in the object cache. + */ +function page_manager_set_page_cache($page) { + if (!empty($page->locked)) { + return; + } + + if (empty($page->task_name)) { + return; + } + + ctools_include('object-cache'); + $page->changed = TRUE; + $cache = ctools_object_cache_set('page_manager_page', $page->task_name, $page); +} + +/** + * Remove an item from the object cache. + */ +function page_manager_clear_page_cache($name) { + ctools_include('object-cache'); + ctools_object_cache_clear('page_manager_page', $name); +} + +/** + * Write all changes from the page cache and clear it out. + */ +function page_manager_save_page_cache($cache) { + // Save the subtask: + if ($function = ctools_plugin_get_function($cache->task, 'save subtask callback')) { + $function($cache->subtask, $cache); + } + + // Iterate through handlers and save/delete/update as necessary. + // Go through each of the task handlers, check to see if it needs updating, + // and update it if so. + foreach ($cache->handler_info as $id => $info) { + $handler = &$cache->handlers[$id]; + // If it has been marked for deletion, delete it. + + if ($info['changed'] & PAGE_MANAGER_CHANGED_DELETED) { + page_manager_delete_task_handler($handler); + } + // If it has been somehow edited (or added), write the cached version + elseif ($info['changed'] & PAGE_MANAGER_CHANGED_CACHED) { + // Make sure we get updated weight from the form for this. + $handler->weight = $info['weight']; + page_manager_save_task_handler($handler); + } + // Otherwise, check to see if it has moved and, if so, update the weight. + elseif ($info['weight'] != $handler->weight) { + // Theoretically we could only do this for in code objects, but since our + // load mechanism checks for all, this is less database work. + page_manager_update_task_handler_weight($handler, $info['weight']); + } + + // Set enable/disabled status. + if ($info['changed'] & PAGE_MANAGER_CHANGED_STATUS) { + ctools_include('export'); + ctools_export_set_object_status($cache->handlers[$id], $info['disabled']); + } + } + + page_manager_clear_page_cache($cache->task_name); + + if (!empty($cache->path_changed) || !empty($cache->new)) { + // Force a menu rebuild to make sure the menu entries are set. + menu_rebuild(); + } + cache_clear_all(); +} + +/** + * Menu callback to load a page manager cache object for menu callbacks. + */ +function page_manager_cache_load($task_name) { + // load context plugin as there may be contexts cached here. + ctools_include('context'); + return page_manager_get_page_cache($task_name); +} + +/** + * Generate a unique name for a task handler. + * + * Task handlers need to be named but they aren't allowed to set their own + * names. Instead, they are named based upon their parent task and type. + */ +function page_manager_handler_get_name($task_name, $handlers, $handler) { + $base = str_replace('-', '_', $task_name); + // Generate a unique name. Unlike most named objects, we don't let people choose + // names for task handlers because they mostly don't make sense. + $base .= '_' . $handler->handler; + + // Once we have a base, check to see if it is used. If it is, start counting up. + $name = $base; + $count = 1; + // If taken + while (isset($handlers[$name])) { + $name = $base . '_' . ++$count; + } + + return $name; +} + +/** + * Import a handler into a page. + * + * This is used by both import and clone, since clone just exports the + * handler and immediately imports it. + */ +function page_manager_handler_add_to_page(&$page, &$handler, $title = NULL) { + $last = end($page->handler_info); + $handler->weight = $last ? $last['weight'] + 1 : 0; + $handler->task = $page->task_id; + $handler->subtask = $page->subtask_id; + $handler->export_type = EXPORT_IN_DATABASE; + $handler->type = t('Normal'); + + if ($title) { + $handler->conf['title'] = $title; + } + + $name = page_manager_handler_get_name($page->task_name, $page->handlers, $handler); + + $handler->name = $name; + + $page->handlers[$name] = $handler; + $page->handler_info[$name] = array( + 'weight' => $handler->weight, + 'name' => $handler->name, + 'changed' => PAGE_MANAGER_CHANGED_CACHED, + ); +} + +// -------------------------------------------------------------------------- +// Database routines +// +// This includes fetching plugins and plugin info as well as specialized +// fetch methods to get groups of task handlers per task. + +/** + * Load a single task handler by name. + * + * Handlers can come from multiple sources; either the database or by normal + * export method, which is handled by the ctools library, but handlers can + * also be bundled with task/subtask. We have to check there and perform + * overrides as appropriate. + * + * Handlers bundled with the task are of a higher priority than default + * handlers provided by normal code, and are of a lower priority than + * the database, so we have to check the source of handlers when we have + * multiple to choose from. + */ +function page_manager_load_task_handler($task, $subtask_id, $name) { + ctools_include('export'); + $result = ctools_export_load_object('page_manager_handlers', 'names', array($name)); + $handlers = page_manager_get_default_task_handlers($task, $subtask_id); + return page_manager_compare_task_handlers($result, $handlers, $name); +} + +/** + * Load all task handlers for a given task/subtask. + */ +function page_manager_load_task_handlers($task, $subtask_id = NULL, $default_handlers = NULL) { + ctools_include('export'); + $conditions = array( + 'task' => $task['name'], + ); + + if (isset($subtask_id)) { + $conditions['subtask'] = $subtask_id; + } + + $handlers = ctools_export_load_object('page_manager_handlers', 'conditions', $conditions); + $defaults = isset($default_handlers) ? $default_handlers : page_manager_get_default_task_handlers($task, $subtask_id); + foreach ($defaults as $name => $default) { + $result = page_manager_compare_task_handlers($handlers, $defaults, $name); + + if ($result) { + $handlers[$name] = $result; + // Ensure task and subtask are correct, because it's easy to change task + // names when editing a default and fail to do it on the associated handlers. + $result->task = $task['name']; + $result->subtask = $subtask_id; + } + } + + // Override weights from the weight table. + if ($handlers) { + $names = array(); + $placeholders = array(); + foreach ($handlers as $handler) { + $names[] = $handler->name; + $placeholders[] = "'%s'"; + } + + $result = db_query("SELECT name, weight FROM {page_manager_weights} WHERE name IN (" . implode(', ', $placeholders) . ")", $names); + while ($weight = db_fetch_object($result)) { + $handlers[$weight->name]->weight = $weight->weight; + } + } + + return $handlers; +} + +/** + * Get the default task handlers from a task, if they exist. + * + * Tasks can contain 'default' task handlers which are provided by the + * default task. Because these can come from either the task or the + * subtask, the logic is abstracted to reduce code duplication. + */ +function page_manager_get_default_task_handlers($task, $subtask_id) { + // Load default handlers that are provied by the task/subtask itself. + $handlers = array(); + if ($subtask_id) { + $subtask = page_manager_get_task_subtask($task, $subtask_id); + if (isset($subtask['default handlers'])) { + $handlers = $subtask['default handlers']; + } + } + else if (isset($task['default handlers'])) { + $handlers = $task['default handlers']; + } + + return $handlers; +} + +/** + * Compare a single task handler from two lists and provide the correct one. + * + * Task handlers can be gotten from multiple sources. As exportable objects, + * they can be provided by default hooks and the database. But also, because + * they are tightly bound to tasks, they can also be provided by default + * tasks. This function reconciles where to pick up a task handler between + * the exportables list and the defaults provided by the task itself. + * + * @param $result + * A list of handlers provided by export.inc + * @param $handlers + * A list of handlers provided by the default task. + * @param $name + * Which handler to compare. + * @return + * Which handler to use, if any. May be NULL. + */ +function page_manager_compare_task_handlers($result, $handlers, $name) { + // Compare our special default handler against the actual result, if + // any, and do the right thing. + if (!isset($result[$name]) && isset($handlers[$name])) { + $handlers[$name]->type = t('Default'); + $handlers[$name]->export_type = EXPORT_IN_CODE; + return $handlers[$name]; + } + else if (isset($result[$name]) && !isset($handlers[$name])) { + return $result[$name]; + } + else if (isset($result[$name]) && isset($handlers[$name])) { + if ($result[$name]->export_type & EXPORT_IN_DATABASE) { + $result[$name]->type = t('Overridden'); + $result[$name]->export_type = $result[$name]->export_type | EXPORT_IN_CODE; + return $result[$name]; + } + else { + // In this case, our default is a higher priority than the standard default. + $handlers[$name]->type = t('Default'); + $handlers[$name]->export_type = EXPORT_IN_CODE; + return $handlers[$name]; + } + } +} + +/** + * Load all task handlers for a given task and subtask and sort them. + */ +function page_manager_load_sorted_handlers($task, $subtask_id = NULL, $enabled = FALSE) { + $handlers = page_manager_load_task_handlers($task, $subtask_id); + if ($enabled) { + foreach ($handlers as $id => $handler) { + if (!empty($handler->disabled)) { + unset($handlers[$id]); + } + } + } + uasort($handlers, 'page_manager_sort_task_handlers'); + return $handlers; +} + +/** + * Callback for uasort to sort task handlers. + * + * Task handlers are sorted by weight then by name. + */ +function page_manager_sort_task_handlers($a, $b) { + if ($a->weight < $b->weight) { + return -1; + } + elseif ($a->weight > $b->weight) { + return 1; + } + elseif ($a->name < $b->name) { + return -1; + } + elseif ($a->name > $b->name) { + return 1; + } + + return 0; +} + +/** + * Write a task handler to the database. + */ +function page_manager_save_task_handler(&$handler) { + $update = (isset($handler->did)) ? array('did') : array(); + // Let the task handler respond to saves: + if ($function = ctools_plugin_load_function('page_manager', 'task_handlers', $handler->handler, 'save')) { + $function($handler, $update); + } + + drupal_write_record('page_manager_handlers', $handler, $update); + db_query("DELETE FROM {page_manager_weights} WHERE name = '%s'", $handler->name); + + // If this was previously a default handler, we may have to write task handlers. + if (!$update) { + // @todo wtf was I going to do here? + } + return $handler; +} + +/** + * Remove a task handler. + */ +function page_manager_delete_task_handler($handler) { + // Let the task handler respond to saves: + if ($function = ctools_plugin_load_function('page_manager', 'task_handlers', $handler->handler, 'delete')) { + $function($handler); + } + db_query("DELETE FROM {page_manager_handlers} WHERE name = '%s'", $handler->name); + db_query("DELETE FROM {page_manager_weights} WHERE name = '%s'", $handler->name); +} + +/** + * Export a task handler into code suitable for import or use as a default + * task handler. + */ +function page_manager_export_task_handler($handler, $indent = '') { + ctools_include('export'); + ctools_include('plugins'); + $handler = drupal_clone($handler); + + $append = ''; + if ($function = ctools_plugin_load_function('page_manager', 'task_handlers', $handler->handler, 'export')) { + $append = $function($handler, $indent); + } + + $output = ctools_export_object('page_manager_handlers', $handler, $indent); + $output .= $append; + + return $output; +} + +/** + * Create a new task handler object. + * + * @param $plugin + * The plugin this task handler is created from. + */ +function page_manager_new_task_handler($plugin) { + // Generate a unique name. Unlike most named objects, we don't let people choose + // names for task handlers because they mostly don't make sense. + + // Create a new, empty handler object. + $handler = new stdClass; + $handler->title = $plugin['title']; + $handler->task = NULL; + $handler->subtask = NULL; + $handler->name = NULL; + $handler->handler = $plugin['name']; + $handler->weight = 0; + $handler->conf = array(); + + // These are provided by the core export API provided by ctools and we + // set defaults here so that we don't cause notices. Perhaps ctools should + // provide a way to do this for us so we don't have to muck with it. + $handler->export_type = EXPORT_IN_DATABASE; + $handler->type = t('Local'); + + if (isset($plugin['default conf'])) { + if (is_array($plugin['default conf'])) { + $handler->conf = $plugin['default conf']; + } + else if (function_exists($plugin['default conf'])) { + $handler->conf = $plugin['default conf']($handler); + } + } + + return $handler; +} + +/** + * Set an overidden weight for a task handler. + * + * We do this so that in-code task handlers don't need to get written + * to the database just because they have their weight changed. + */ +function page_manager_update_task_handler_weight($handler, $weight) { + db_query("DELETE FROM {page_manager_weights} WHERE name = '%s'", $handler->name); + db_query("INSERT INTO {page_manager_weights} (name, weight) VALUES ('%s', %d)", $handler->name, $weight); +} + + +/** + * Shortcut function to get task plugins. + */ +function page_manager_get_tasks() { + ctools_include('plugins'); + return ctools_get_plugins('page_manager', 'tasks'); +} + +/** + * Shortcut function to get a task plugin. + */ +function page_manager_get_task($id) { + ctools_include('plugins'); + return ctools_get_plugins('page_manager', 'tasks', $id); +} + +/** + * Get all tasks for a given type. + */ +function page_manager_get_tasks_by_type($type) { + ctools_include('plugins'); + $all_tasks = ctools_get_plugins('page_manager', 'tasks'); + $tasks = array(); + foreach ($all_tasks as $id => $task) { + if (isset($task['task type']) && $task['task type'] == $type) { + $tasks[$id] = $task; + } + } + + return $tasks; +} + +/** + * Fetch all subtasks for a page managertask. + * + * @param $task + * A loaded $task plugin object. + */ +function page_manager_get_task_subtasks($task) { + if (empty($task['subtasks'])) { + return array(); + } + + if ($function = ctools_plugin_get_function($task, 'subtasks callback')) { + return $function($task); + } + + return array(); +} + +/** + * Fetch all subtasks for a page managertask. + * + * @param $task + * A loaded $task plugin object. + * @param $subtask_id + * The subtask ID to load. + */ +function page_manager_get_task_subtask($task, $subtask_id) { + if (empty($task['subtasks'])) { + return; + } + + if ($function = ctools_plugin_get_function($task, 'subtask callback')) { + return $function($task, $subtask_id); + } +} + +/** + * Shortcut function to get task handler plugins. + */ +function page_manager_get_task_handlers() { + ctools_include('plugins'); + return ctools_get_plugins('page_manager', 'task_handlers'); +} + +/** + * Shortcut function to get a task handler plugin. + */ +function page_manager_get_task_handler($id) { + ctools_include('plugins'); + return ctools_get_plugins('page_manager', 'task_handlers', $id); +} + +/** + * Retrieve a list of all applicable task handlers for a given task. + * + * This looks at the $task['handler type'] and compares that to $task_handler['handler type']. + * If the task has no type, the id of the task is used instead. + */ +function page_manager_get_task_handler_plugins($task, $all = FALSE) { + $type = isset($task['handler type']) ? $task['handler type'] : $task['name']; + $name = $task['name']; + + $handlers = array(); + $task_handlers = page_manager_get_task_handlers(); + foreach ($task_handlers as $id => $handler) { + $task_type = is_array($handler['handler type']) ? $handler['handler type'] : array($handler['handler type']); + if (in_array($type, $task_type) || in_array($name, $task_type)) { + if ($all || !empty($handler['visible'])) { + $handlers[$id] = $handler; + } + } + } + + return $handlers; +} + +/** + * Get the title for a given handler. + * + * If the plugin has no 'admin title' function, the generic title of the + * plugin is used instead. + */ +function page_manager_get_handler_title($plugin, $handler, $task, $subtask_id) { + $function = ctools_plugin_get_function($plugin, 'admin title'); + if ($function) { + return $function($handler, $task, $subtask_id); + } + else { + return $plugin['title']; + } +} + +/** + * Get the admin summary (additional info) for a given handler. + */ +function page_manager_get_handler_summary($plugin, $handler, $page, $title = TRUE) { + if ($function = ctools_plugin_get_function($plugin, 'admin summary')) { + return $function($handler, $page->task, $page->subtask, $page, $title); + } +} + +/** + * Get the admin summary (additional info) for a given page. + */ +function page_manager_get_page_summary($task, $subtask) { + if ($function = ctools_plugin_get_function($subtask, 'admin summary')) { + return $function($task, $subtask); + } +} + +/** + * Split a task name into a task id and subtask id, if applicable. + */ +function page_manager_get_task_id($task_name) { + if (strpos($task_name, '-') !== FALSE) { + return explode('-', $task_name, 2); + } + else { + return array($task_name, NULL); + } +} + +/** + * Turn a task id + subtask_id into a task name. + */ +function page_manager_make_task_name($task_id, $subtask_id) { + if ($subtask_id) { + return $task_id . '-' . $subtask_id; + } + else { + return $task_id; + } +} + +/** + * Get the render function for a handler. + */ +function page_manager_get_renderer($handler) { + return ctools_plugin_load_function('page_manager', 'task_handlers', $handler->handler, 'render'); +} + +// -------------------------------------------------------------------------- +// Functions existing on behalf of tasks and task handlers + + +/** + * Page manager arg load function because menu system will not load extra + * files for these; they must be in a .module. + */ +function pm_arg_load($value, $subtask, $argument) { + page_manager_get_task('page'); + return _pm_arg_load($value, $subtask, $argument); +} + +/** + * Special arg_load function to use %menu_tail like functionality to + * get everything after the arg together as a single value. + */ +function pm_arg_tail_load($value, $subtask, $argument, $map) { + $value = implode('/', array_slice($map, $argument)); + page_manager_get_task('page'); + return _pm_arg_load($value, $subtask, $argument); +} + +/** + * Special menu _load() function for the user:uid argument. + * + * This is just the normal page manager argument. It only exists so that + * the to_arg can exist. + */ +function pm_uid_arg_load($value, $subtask, $argument) { + page_manager_get_task('page'); + return _pm_arg_load($value, $subtask, $argument); +} + +/** + * to_arg function for the user:uid argument to provide the arg for the + * current global user. + */ +function pm_uid_arg_to_arg($arg) { + return user_uid_optional_to_arg($arg); +} + +/** + * Callback for access control ajax form on behalf of page.inc task. + * + * Returns the cached access config and contexts used. + */ +function page_manager_page_ctools_access_get($argument) { + $page = page_manager_get_page_cache($argument); + + $contexts = array(); + + // Load contexts based on argument data: + if ($arguments = _page_manager_page_get_arguments($page->subtask['subtask'])) { + $contexts = ctools_context_get_placeholders_from_argument($arguments); + } + + return array($page->subtask['subtask']->access, $contexts); +} + +/** + * Callback for access control ajax form on behalf of page.inc task. + * + * Writes the changed access to the cache. + */ +function page_manager_page_ctools_access_set($argument, $access) { + $page = page_manager_get_page_cache($argument); + $page->subtask['subtask']->access = $access; + page_manager_set_page_cache($page); +} + +/** + * Callback for access control ajax form on behalf of context task handler. + * + * Returns the cached access config and contexts used. + */ +function page_manager_task_handler_ctools_access_get($argument) { + list($task_name, $name) = explode('*', $argument); + $page = page_manager_get_page_cache($task_name); + if (empty($name)) { + $handler = &$page->new_handler; + } + else { + $handler = &$page->handlers[$name]; + } + + if (!isset($handler->conf['access'])) { + $handler->conf['access'] = array(); + } + + ctools_include('context-task-handler'); + + $contexts = ctools_context_handler_get_all_contexts($page->task, $page->subtask, $handler); + + return array($handler->conf['access'], $contexts); +} + +function page_manager_context_cache_get($task_name, $key) { + $page = page_manager_get_page_cache($task_name); + if ($page) { + if (!empty($page->context_cache[$key])) { + return $page->context_cache[$key]; + } + else { + ctools_include('context-task-handler'); + if ($key == 'temp') { + $handler = $page->new_handler; + } + else { + $handler = $page->handlers[$key]; + } + return ctools_context_handler_get_task_object($page->task, $page->subtask, $handler); + } + } +} + +function page_manager_context_cache_set($task_name, $key, $object) { + $page = page_manager_get_page_cache($task_name); + if ($page) { + $page->context_cache[$key] = $object; + page_manager_set_page_cache($page); + } +} + +/** + * Callback for access control ajax form on behalf of context task handler. + * + * Writes the changed access to the cache. + */ +function page_manager_task_handler_ctools_access_set($argument, $access) { + list($task_name, $name) = explode('*', $argument); + $page = page_manager_get_page_cache($task_name); + if (empty($name)) { + $handler = &$page->new_handler; + } + else { + $handler = &$page->handlers[$name]; + } + + $handler->conf['access'] = $access; + page_manager_set_page_cache($page); +} + +/** + * Form a URL to edit a given page given the trail. + */ +function page_manager_edit_url($task_name, $trail = array()) { + if (!is_array($trail)) { + $trail = array($trail); + } + + if (empty($trail) || $trail == array('summary')) { + return "admin/build/pages/edit/$task_name"; + } + + return 'admin/build/pages/nojs/operation/' . $task_name . '/' . implode('/', $trail); +} + +/** + * Watch menu links during the menu rebuild, and re-parent things if we need to. + */ +function page_manager_menu_link_alter(&$item, $menu) { + return; +/** -- disabled, concept code -- + static $mlids = array(); + // Keep an array of mlids as links are saved that we can use later. + if (isset($item['mlid'])) { + $mlids[$item['path']] = $item['mlid']; + } + + if (isset($item['parent_path'])) { + if (isset($mlids[$item['parent_path']])) { + $item['plid'] = $mlids[$item['parent_path']]; + } + else { + // Since we didn't already see an mlid, let's check the database for one. + $mlid = db_result(db_query("SELECT mlid FROM {menu_links} WHERE router_path = '%s'", $item['parent_path'])); + if ($mlid) { + $item['plid'] = $mlid; + } + } + } + */ +} + +/** + * Callback to list handlers available for export. + */ +function page_manager_page_manager_handlers_list() { + $list = $types = array(); + $tasks = page_manager_get_tasks(); + foreach ($tasks as $type => $info) { + if (empty($info['non-exportable'])) { + $types[] = $type; + } + } + + $handlers = ctools_export_load_object('page_manager_handlers'); + foreach ($handlers as $handler) { + if (in_array($handler->task, $types)) { + $plugin = page_manager_get_task_handler($handler->handler); + $title = page_manager_get_handler_title($plugin, $handler, $tasks[$handler->task], $handler->subtask); + + if ($title) { + $list[$handler->name] = check_plain("$handler->task: $title ($handler->name)"); + } + else { + $list[$handler->name] = check_plain("$handler->task: ($handler->name)"); + } + } + } + return $list; +} + +/** + * Callback to bulk export page manager pages. + */ +function page_manager_page_manager_pages_to_hook_code($names = array(), $name = 'foo') { + $schema = ctools_export_get_schema('page_manager_pages'); + $export = $schema['export']; + $objects = ctools_export_load_object('page_manager_pages', 'names', array_values($names)); + if ($objects) { + $code = "/**\n"; + $code .= " * Implementation of hook_{$export['default hook']}()\n"; + $code .= " */\n"; + $code .= "function " . $name . "_{$export['default hook']}() {\n"; + foreach ($objects as $object) { + // Have to implement our own because this export func sig requires it + $code .= $export['export callback']($object, TRUE, ' '); + $code .= " \${$export['identifier']}s['" . check_plain($object->$export['key']) . "'] = \${$export['identifier']};\n\n"; + } + $code .= " return \${$export['identifier']}s;\n"; + $code .= "}\n"; + return $code; + } +} + +/** + * Get the current page information. + * + * @return $page + * An array containing the following information. + * + * - 'name': The name of the page as used in the page manager admin UI. + * - 'task': The plugin for the task in use. If this is a system page it + * will contain information about that page, such as what functions + * it uses. + * - 'subtask': The plugin for the subtask. If this is a custom page, this + * will contain information about that custom page. See 'subtask' in this + * array to get the actual page object. + * - 'handler': The actual handler object used. If using panels, see + * $page['handler']->conf['display'] for the actual panels display + * used to render. + * - 'contexts': The context objects used to render this page. + * - 'arguments': The raw arguments from the URL used on this page. + */ +function page_manager_get_current_page($page = NULL) { + static $current = array(); + if (isset($page)) { + $current = $page; + } + + return $current; +} + +/** + * Implementation of hook_panels_dashboard_blocks(). + * + * Adds page information to the Panels dashboard. + */ +function page_manager_panels_dashboard_blocks(&$vars) { + $vars['links']['page_manager'] = array( + 'weight' => -100, + 'title' => l(t('Panel page'), 'admin/build/pages/add'), + 'description' => t('Panel pages can be used as landing pages. They have a URL path, accept arguments and can have menu entries.'), + ); + + module_load_include('inc', 'page_manager', 'page_manager.admin'); + $tasks = page_manager_get_tasks_by_type('page'); + $pages = array('operations' => array()); + + page_manager_get_pages($tasks, $pages); + $count = 0; + $rows = array(); + foreach ($pages['rows'] as $id => $info) { + $rows[] = array( + 'data' => array( + $info['data']['title'], + $info['data']['operations'], + ), + 'class' => $info['class'], + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + + $vars['blocks']['page_manager'] = array( + 'weight' => -100, + 'title' => t('Manage pages'), + 'link' => l(t('Go to list'), 'admin/build/pages'), + 'content' => theme('table', array(), $rows, array('class' => 'panels-manage')), + 'class' => 'dashboard-pages', + 'section' => 'right', + ); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/task_handlers/http_response.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/task_handlers/http_response.inc new file mode 100644 index 0000000000000000000000000000000000000000..a07327352ee144c5deae7b8840d29d424e73d78b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/task_handlers/http_response.inc @@ -0,0 +1,288 @@ +<?php + +/** + * @file + * + * This is the task handler plugin to handle generating 403, 404 and 301 response codes. + */ + +// Plugin definition +$plugin = array( + // is a 'context' handler type, meaning it supports the API of the + // context handlers provided by ctools context plugins. + 'handler type' => 'context', + 'visible' => TRUE, // may be added up front. + + // Administrative fields. + 'title' => t('HTTP response code'), + 'admin summary' =>'page_manager_http_response_admin_summary', + 'admin title' => 'page_manager_http_response_title', + 'operations' => array( + 'settings' => array( + 'title' => t('General'), + 'description' => t('Change general settings for this variant.'), + 'form' => 'page_manager_http_response_edit_settings', + ), + 'criteria' => array( + 'title' => t('Selection rules'), + 'description' => t('Control the criteria used to decide whether or not this variant is used.'), + 'ajax' => FALSE, + 'form' => array( + 'order' => array( + 'form' => t('Selection rules'), + ), + 'forms' => array( + 'form' => array( + 'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc', + 'form id' => 'ctools_context_handler_edit_criteria', + ), + ), + ), + ), + 'context' => array( + 'title' => t('Contexts'), + 'ajax' => FALSE, + 'description' => t('Add additional context objects to this variant that can be used by the content.'), + 'form' => array( + 'order' => array( + 'form' => t('Context'), + ), + 'forms' => array( + 'form' => array( + 'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc', + 'form id' => 'ctools_context_handler_edit_context', + ), + ), + ), + ), + ), + + // Callback to render the data. + 'render' => 'page_manager_http_response_render', + + 'add features' => array( + 'criteria' => t('Selection rules'), + 'context' => t('Contexts'), + ), + // Where to go when finished. + 'add finish' => 'settings', + + 'required forms' => array( + 'settings' => t('HTTP Response settings'), + ), + + 'edit forms' => array( + 'criteria' => t('Selection rules'), + 'settings' => t('General'), + 'context' => t('Contexts'), + ), + 'forms' => array( + 'settings' => array( + 'form id' => 'page_manager_http_response_edit_settings', + ), + 'context' => array( + 'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc', + 'form id' => 'ctools_context_handler_edit_context', + ), + 'criteria' => array( + 'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc', + 'form id' => 'ctools_context_handler_edit_criteria', + ), + ), + 'default conf' => array( + 'title' => t('HTTP response code'), + 'contexts' => array(), + 'relationships' => array(), + 'code' => '404', + 'destination' => '', + ), +); + +/** + * Provide a list of the response codes we support. + * + * Abstracted so it can be more readily used both on input and output. + */ +function page_manager_http_response_codes() { + return array( + 404 => t('404 Page not found'), + 403 => t('403 Access denied'), + 301 => t('301 Redirect'), + ); +} + +function page_manager_http_response_admin_summary($handler, $task, $subtask, $page, $show_title = TRUE) { + $task_name = page_manager_make_task_name($task['name'], $subtask['name']); + $output = ''; + + ctools_include('context'); + ctools_include('context-task-handler'); + + // Get the operations + $operations = page_manager_get_operations($page); + + // Get operations for just this handler. + $operations = $operations['handlers']['children'][$handler->name]['children']['actions']['children']; + $args = array('handlers', $handler->name, 'actions'); + $rendered_operations = page_manager_render_operations($page, $operations, array(), array('class' => 'actions'), 'actions', $args); + + $plugin = page_manager_get_task_handler($handler->handler); + + $object = ctools_context_handler_get_task_object($task, $subtask, $handler); + $context = ctools_context_load_contexts($object, TRUE); + + $access = ctools_access_group_summary(!empty($handler->conf['access']) ? $handler->conf['access'] : array(), $context); + if ($access) { + $access = t('This task will be selected if @conditions.', array('@conditions' => $access)); + } + else { + $access = t('This task will always be selected.'); + } + + $rows = array(); + + $type = $handler->type == t('Default') ? t('In code') : $handler->type; + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Storage')), + array('class' => t('page-summary-data'), 'data' => $type), + array('class' => t('page-summary-operation'), 'data' => ''), + ); + + if (!empty($handler->disabled)) { + $link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'enable'))); + $text = t('Disabled'); + } + else { + $link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'disable'))); + $text = t('Enabled'); + } + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Status')), + array('class' => t('page-summary-data'), 'data' => $text), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + $link = l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'criteria'))); + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Selection rule')), + array('class' => t('page-summary-data'), 'data' => $access), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + $link = l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'settings'))); + $codes = page_manager_http_response_codes(); + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Response code')), + array('class' => t('page-summary-data'), 'data' => $codes[$handler->conf['code']]), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + $info = theme('table', array(), $rows, array('class' => 'page-manager-handler-summary')); + + $title = $handler->conf['title']; + if ($title != t('HTTP Response')) { + $title = t('HTTP Response: @title', array('@title' => $title)); + } + + $output .= '<div class="clear-block">'; + if ($show_title) { + $output .= '<div class="handler-title clear-block">'; + $output .= '<div class="actions handler-actions">' . $rendered_operations['actions'] . '</div>'; + $output .= '<span class="title-label">' . $title . '</span>'; + } + + $output .= '</div>'; + $output .= $info; + $output .= '</div>'; + + return $output; +} + +/** + * Set up a title for the handler based upon the selection rules. + */ +function page_manager_http_response_title($handler, $task, $subtask) { + if (isset($handler->conf['title'])) { + return check_plain($handler->conf['title']); + } + else { + return t('HTTP response code'); + } +} + +/** + * General settings for the handler + */ +function page_manager_http_response_edit_settings(&$form, &$form_state) { + $conf = $form_state['handler']->conf; + $form['title'] = array( + '#type' => 'textfield', + '#default_value' => $conf['title'], + '#title' => t('Administrative title'), + '#description' => t('Administrative title of this variant.'), + ); + + $form['code'] = array( + '#title' => t('Response code'), + '#type' => 'select', + '#options' => page_manager_http_response_codes(), + '#default_value' => $conf['code'], + ); + + ctools_include('dependent'); + $form['destination'] = array( + '#type' => 'textfield', + '#title' => t('Redirect destination'), + '#default_value' => $conf['destination'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-code' => array(301)), + '#description' => t('Enter the path to redirect to. You may use keyword substitutions from contexts. You can use external urls (http://www.example.com/foo) or internal urls (node/1).'), + ); +} + +function page_manager_http_response_edit_settings_submit(&$form, &$form_state) { + $form_state['handler']->conf['title'] = $form_state['values']['title']; + $form_state['handler']->conf['code'] = $form_state['values']['code']; + $form_state['handler']->conf['destination'] = $form_state['values']['destination']; +} + +function page_manager_http_response_render($handler, $base_contexts, $args, $test = TRUE) { + // Go through arguments and see if they match. + ctools_include('context'); + ctools_include('context-task-handler'); + + // Add my contexts + $contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler); + + // Test. + if ($test && !ctools_context_handler_select($handler, $contexts)) { + return; + } + + if (isset($handler->handler)) { + ctools_context_handler_pre_render($handler, $contexts, $args); + } + + $info['response code'] = $handler->conf['code']; + if ($info['response code'] == 301) { + $path = ctools_context_keyword_substitute($handler->conf['destination'], array(), $contexts); + $url = parse_url($path); + if (isset($url['query'])) { + $path = strtr($path, array('?' . $url['query'] => '')); + $info['query'] = array(); + foreach (explode('&', $url['query']) as $query_part) { + list($key, $value) = explode('=', $query_part); + $info['query'][$key] = $value; + } + } + if (isset($url['fragment'])) { + $path = strtr($path, array('#' . $url['fragment'] => '')); + $info['fragment'] = $url['fragment']; + } + + $info['destination'] = rtrim($path, '?'); + } + + return $info; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/blog.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/blog.inc new file mode 100644 index 0000000000000000000000000000000000000000..8d62e98ddd1b2a7cb91dca96218fdb6529d32ae7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/blog.inc @@ -0,0 +1,104 @@ +<?php + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_blog_page_manager_tasks() { + if (!module_exists('blog')) { + return; + } + + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + + 'title' => t('All blogs'), + 'admin title' => t('All blogs'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for the all blogs at <em>/blog</em>. If no variant is selected, the default Drupal most recent blog posts will be shown.'), + 'admin path' => 'blog', + + // Menu hooks so that we can alter the node/%node menu entry to point to us. + 'hook menu alter' => 'page_manager_blog_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_blog_disabled', TRUE), + 'enable callback' => 'page_manager_blog_enable', + ); +} + +/** + * Callback defined by page_manager_blog_page_manager_tasks(). + * + * Alter the node edit input so that node edit comes to us rather than the + * normal node edit process. + */ +function page_manager_blog_menu_alter(&$items, $task) { + if (variable_get('page_manager_blog_disabled', TRUE)) { + return; + } + + $callback = $items['blog']['page callback']; + // Override the node edit handler for our purpose. + if ($callback == 'blog_page_last' || variable_get('page_manager_override_anyway', FALSE)) { + $items['blog']['page callback'] = 'page_manager_blog'; + $items['blog']['file path'] = $task['path']; + $items['blog']['file'] = $task['file']; + } + else { + variable_set('page_manager_blog_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_blog'])) { + drupal_set_message(t('Page manager module is unable to enable blog because some other module already has overridden with %callback.', array('%callback' => $callback)), 'warning'); + } + return; + } + +} + +/** + * Entry point for our overridden node edit. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * node edit, which is node_page_edit(). + */ +function page_manager_blog() { + // Load my task plugin + $task = page_manager_get_task('blog'); + + ctools_include('context'); + ctools_include('context-task-handler'); + $output = ctools_context_handler_render($task, '', array(), array()); + if ($output !== FALSE) { + return $output; + } + + module_load_include('inc', 'blog', 'blog.pages'); + $function = 'blog_page_last'; + foreach (module_implements('page_manager_override') as $module) { + $call = $module . '_page_manager_override'; + if (($rc = $call('blog')) && function_exists($rc)) { + $function = $rc; + break; + } + } + + // Otherwise, fall back. + return $function(); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_blog_enable($cache, $status) { + variable_set('page_manager_blog_disabled', $status); + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_blog'] = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/blog_user.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/blog_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..8ad43d01c810b01a2cbb19478cf54a39aaa99e73 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/blog_user.inc @@ -0,0 +1,134 @@ +<?php + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_blog_user_page_manager_tasks() { + if (!module_exists('blog')) { + return; + } + + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + 'title' => t('User blog'), + 'admin title' => t('User blog'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for displaying user blogs at <em>blog/%user</em>. If no variant is selected, the default Drupal user blog will be used.'), + 'admin path' => 'blog/%user', + + // Callback to add items to the page managertask administration form: + 'task admin' => 'page_manager_blog_user_task_admin', + + 'hook menu alter' => 'page_manager_blog_user_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', // handler type -- misnamed + 'get arguments' => 'page_manager_blog_user_get_arguments', + 'get context placeholders' => 'page_manager_blog_user_get_contexts', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_blog_user_disabled', TRUE), + 'enable callback' => 'page_manager_blog_user_enable', + ); +} + +/** + * Callback defined by page_manager_blog_user_page_manager_tasks(). + * + * Alter the user view input so that user view comes to us rather than the + * normal user view process. + */ +function page_manager_blog_user_menu_alter(&$items, $task) { + if (variable_get('page_manager_blog_user_disabled', TRUE)) { + return; + } + + // Override the user view handler for our purpose. + if ($items['blog/%user_uid_optional']['page callback'] == 'blog_page_user' || variable_get('page_manager_override_anyway', FALSE)) { + $items['blog/%user_uid_optional']['page callback'] = 'page_manager_blog_user'; + $items['blog/%user_uid_optional']['file path'] = $task['path']; + $items['blog/%user_uid_optional']['file'] = $task['file']; + } + else { + // automatically disable this task if it cannot be enabled. + variable_set('page_manager_blog_user_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_blog_user'])) { + drupal_set_message(t('Page manager module is unable to enable blog/%user because some other module already has overridden with %callback.', array('%callback' => $items['blog/%user']['page callback'])), 'error'); + } + } +} + +/** + * Entry point for our overridden user view. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * user view, which is user_page_view(). + */ +function page_manager_blog_user($account) { + // Load my task plugin: + $task = page_manager_get_task('blog_user'); + + // Load the account into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($account)); + + $output = ctools_context_handler_render($task, '', $contexts, array($account->uid)); + if ($output !== FALSE) { + return $output; + } + + module_load_include('inc', 'blog', 'blog.pages'); + $function = 'blog_page_user'; + foreach (module_implements('page_manager_override') as $module) { + $call = $module . '_page_manager_override'; + if (($rc = $call('blog_user')) && function_exists($rc)) { + $function = $rc; + break; + } + } + + // Otherwise, fall back. + return $function($account); +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the node view and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function page_manager_blog_user_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'user', + 'identifier' => t('User being viewed'), + 'id' => 1, + 'name' => 'uid', + 'settings' => array(), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function page_manager_blog_user_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(page_manager_blog_user_get_arguments($task, $subtask_id)); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_blog_user_enable($cache, $status) { + variable_set('page_manager_blog_user_disabled', $status); + + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_blog_user'] = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/contact_site.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/contact_site.inc new file mode 100644 index 0000000000000000000000000000000000000000..d55f4c4d5290cd0316b00d08a7f8beb0dac90cf8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/contact_site.inc @@ -0,0 +1,104 @@ +<?php + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_contact_site_page_manager_tasks() { + if (!module_exists('contact')) { + return; + } + + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + + 'title' => t('Site contact page'), + 'admin title' => t('Site contact page'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for the site contact page at <em>/contact</em>. If no variant is selected, the default Drupal contact form will be used.'), + 'admin path' => 'contact', + + // Menu hooks so that we can alter the node/%node menu entry to point to us. + 'hook menu alter' => 'page_manager_contact_site_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_contact_site_disabled', TRUE), + 'enable callback' => 'page_manager_contact_site_enable', + ); +} + +/** + * Callback defined by page_manager_contact_site_page_manager_tasks(). + * + * Alter the node edit input so that node edit comes to us rather than the + * normal node edit process. + */ +function page_manager_contact_site_menu_alter(&$items, $task) { + if (variable_get('page_manager_contact_site_disabled', TRUE)) { + return; + } + + $callback = $items['contact']['page callback']; + // Override the node edit handler for our purpose. + if ($callback == 'contact_site_page' || variable_get('page_manager_override_anyway', FALSE)) { + $items['contact']['page callback'] = 'page_manager_contact_site'; + $items['contact']['file path'] = $task['path']; + $items['contact']['file'] = $task['file']; + } + else { + variable_set('page_manager_contact_site_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_contact_site'])) { + drupal_set_message(t('Page manager module is unable to enable contact because some other module already has overridden with %callback.', array('%callback' => $callback)), 'warning'); + } + return; + } + +} + +/** + * Entry point for our overridden node edit. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * node edit, which is node_page_edit(). + */ +function page_manager_contact_site() { + // Load my task plugin + $task = page_manager_get_task('contact_site'); + + ctools_include('context'); + ctools_include('context-task-handler'); + $output = ctools_context_handler_render($task, '', array(), array()); + if ($output !== FALSE) { + return $output; + } + + module_load_include('inc', 'contact', 'contact.pages'); + $function = 'contact_site_page'; + foreach (module_implements('page_manager_override') as $module) { + $call = $module . '_page_manager_override'; + if (($rc = $call('contact_site')) && function_exists($rc)) { + $function = $rc; + break; + } + } + + // Otherwise, fall back. + return $function(); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_contact_site_enable($cache, $status) { + variable_set('page_manager_contact_site_disabled', $status); + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_contact_site'] = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/contact_user.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/contact_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..e376a26e94c7c9e8785a6dea68bbfedd6b0b8bfa --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/contact_user.inc @@ -0,0 +1,133 @@ +<?php + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_contact_user_page_manager_tasks() { + if (!module_exists('contact')) { + return; + } + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + 'title' => t('User contact'), + 'admin title' => t('User contact'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for displaying the user contact form at <em>user/%user/contact</em>. If no variant is selected, the default Drupal user contact form will be used.'), + 'admin path' => 'user/%user/contact', + + // Callback to add items to the page managertask administration form: + 'task admin' => 'page_manager_contact_user_task_admin', + + 'hook menu alter' => 'page_manager_contact_user_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', // handler type -- misnamed + 'get arguments' => 'page_manager_contact_user_get_arguments', + 'get context placeholders' => 'page_manager_contact_user_get_contexts', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_contact_user_disabled', TRUE), + 'enable callback' => 'page_manager_contact_user_enable', + ); +} + +/** + * Callback defined by page_manager_contact_user_page_manager_tasks(). + * + * Alter the user view input so that user view comes to us rather than the + * normal user view process. + */ +function page_manager_contact_user_menu_alter(&$items, $task) { + if (variable_get('page_manager_contact_user_disabled', TRUE)) { + return; + } + + // Override the user view handler for our purpose. + if ($items['user/%user/contact']['page callback'] == 'contact_user_page' || variable_get('page_manager_override_anyway', FALSE)) { + $items['user/%user/contact']['page callback'] = 'page_manager_contact_user'; + $items['user/%user/contact']['file path'] = $task['path']; + $items['user/%user/contact']['file'] = $task['file']; + } + else { + // automatically disable this task if it cannot be enabled. + variable_set('page_manager_contact_user_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_contact_user'])) { + drupal_set_message(t('Page manager module is unable to enable user/%user/contact because some other module already has overridden with %callback.', array('%callback' => $items['user/%user/contact']['page callback'])), 'error'); + } + } +} + +/** + * Entry point for our overridden user view. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * user view, which is user_page_view(). + */ +function page_manager_contact_user($account) { + // Load my task plugin: + $task = page_manager_get_task('contact_user'); + + // Load the account into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($account)); + + $output = ctools_context_handler_render($task, '', $contexts, array($account->uid)); + if ($output !== FALSE) { + return $output; + } + + module_load_include('inc', 'contact', 'contact.pages'); + $function = 'contact_user_page'; + foreach (module_implements('page_manager_override') as $module) { + $call = $module . '_page_manager_override'; + if (($rc = $call('contact_user')) && function_exists($rc)) { + $function = $rc; + break; + } + } + + // Otherwise, fall back. + return $function($account); +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the node view and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function page_manager_contact_user_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'user', + 'identifier' => t('User being viewed'), + 'id' => 1, + 'name' => 'uid', + 'settings' => array(), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function page_manager_contact_user_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(page_manager_contact_user_get_arguments($task, $subtask_id)); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_contact_user_enable($cache, $status) { + variable_set('page_manager_contact_user_disabled', $status); + + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_contact_user'] = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/node_edit.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/node_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..251a18d768df8ea4f5896af203891268e40e7e5d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/node_edit.inc @@ -0,0 +1,167 @@ +<?php + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_node_edit_page_manager_tasks() { + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + + 'title' => t('Node add/edit form'), + 'admin title' => t('Node add/edit form'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for adding or edit nodes at <em>node/%node/edit</em> and <em>node/add/%node_type</em>. If you add variants, you may use selection criteria such as node type or language or user access to provide different edit forms for nodes. If no variant is selected, the default Drupal node edit will be used.'), + 'admin path' => 'node/%node/edit', + + // Menu hooks so that we can alter the node/%node menu entry to point to us. + 'hook menu' => 'page_manager_node_edit_menu', + 'hook menu alter' => 'page_manager_node_edit_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', + 'get arguments' => 'page_manager_node_edit_get_arguments', + 'get context placeholders' => 'page_manager_node_edit_get_contexts', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_node_edit_disabled', TRUE), + 'enable callback' => 'page_manager_node_edit_enable', + ); +} + +/** + * Callback defined by page_manager_node_edit_page_manager_tasks(). + * + * Alter the node edit input so that node edit comes to us rather than the + * normal node edit process. + */ +function page_manager_node_edit_menu_alter(&$items, $task) { + if (variable_get('page_manager_node_edit_disabled', TRUE)) { + return; + } + + $callback = $items['node/%node/edit']['page callback']; + // Override the node edit handler for our purpose. + if ($callback == 'node_page_edit' || variable_get('page_manager_override_anyway', FALSE)) { + $items['node/%node/edit']['page callback'] = 'page_manager_node_edit'; + $items['node/%node/edit']['file path'] = $task['path']; + $items['node/%node/edit']['file'] = $task['file']; + } + else { + variable_set('page_manager_node_edit_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_node_edit'])) { + drupal_set_message(t('Page manager module is unable to enable node/%node/edit because some other module already has overridden with %callback.', array('%callback' => $callback)), 'warning'); + } + return; + } + + // Also catch node/add handling: + foreach (node_get_types('types', NULL, TRUE) as $type) { + $path = 'node/add/' . str_replace('_', '-', $type->type); + if ($items[$path]['page callback'] != 'node_add') { + if (!empty($GLOBALS['page_manager_enabling_node_edit'])) { + drupal_set_message(t('Page manager module is unable to override @path because some other module already has overridden with %callback. Node edit will be enabled but that edit path will not be overridden.', array('@path' => $path, '%callback' => $items[$path]['page callback'])), 'warning'); + } + continue; + } + + $items[$path]['page callback'] = 'page_manager_node_add'; + $items[$path]['file path'] = $task['path']; + $items[$path]['file'] = $task['file']; + // Why str_replace things back? + $items[$path]['page arguments'] = array($type->type); + } +} + +/** + * Entry point for our overridden node edit. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * node edit, which is node_page_edit(). + */ +function page_manager_node_edit($node) { + // Load my task plugin + $task = page_manager_get_task('node_edit'); + + // Load the node into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($node)); + + $arg = array(isset($node->nid) ? $node->nid : $node->type); + $output = ctools_context_handler_render($task, '', $contexts, $arg); + if ($output === FALSE) { + // Fall back! + // We've already built the form with the context, so we can't build it again, or + // form_clean_id will mess up our ids. But we don't really need to, either: + $context = current($contexts); + $output = drupal_render_form($context->form_id, $context->form); + } + + return $output; +} + +/** + * Callback to handle the process of adding a node. + * + * This creates a basic $node and passes that off to page_manager_node_edit(). + * It is modeled after Drupal's node_add() function. + * + * Unlike node_add() we do not need to check node_access because that was + * already checked by the menu system. + */ +function page_manager_node_add($type) { + global $user; + + $types = node_get_types(); + + // Initialize settings: + $node = (object) array( + 'uid' => $user->uid, + 'name' => (isset($user->name) ? $user->name : ''), + 'type' => $type, + 'language' => '', + ); + + drupal_set_title(t('Create @name', array('@name' => $types[$type]->name))); + return page_manager_node_edit($node); +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the node edit and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function page_manager_node_edit_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'node', + 'identifier' => t('Node being edited'), + 'id' => 1, + 'name' => 'node_edit', + 'settings' => array(), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function page_manager_node_edit_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(page_manager_node_edit_get_arguments($task, $subtask_id)); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_node_edit_enable($cache, $status) { + variable_set('page_manager_node_edit_disabled', $status); + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_node_edit'] = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/node_view.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/node_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..83ea01e7a7acf171182c9c1fd1de9605f4ed25f8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/node_view.inc @@ -0,0 +1,146 @@ +<?php + +/** + * @file + * Handle the 'node view' override task. + * + * This plugin overrides node/%node and reroutes it to the page manager, where + * a list of tasks can be used to service this request based upon criteria + * supplied by access plugins. + */ + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_node_view_page_manager_tasks() { + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + + 'title' => t('Node template'), + + 'admin title' => t('Node template'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for displaying nodes at <em>node/%node</em>. If you add variants, you may use selection criteria such as node type or language or user access to provide different views of nodes. If no variant is selected, the default Drupal node view will be used. This page only affects nodes viewed as pages, it will not affect nodes viewed in lists or at other locations. Also please note that if you are using pathauto, aliases may make a node to be somewhere else, but as far as Drupal is concerned, they are still at node/%node.'), + 'admin path' => 'node/%node', + + // Menu hooks so that we can alter the node/%node menu entry to point to us. + 'hook menu' => 'page_manager_node_view_menu', + 'hook menu alter' => 'page_manager_node_view_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', + 'get arguments' => 'page_manager_node_view_get_arguments', + 'get context placeholders' => 'page_manager_node_view_get_contexts', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_node_view_disabled', TRUE), + 'enable callback' => 'page_manager_node_view_enable', + ); +} + +/** + * Callback defined by page_manager_node_view_page_manager_tasks(). + * + * Alter the node view input so that node view comes to us rather than the + * normal node view process. + */ +function page_manager_node_view_menu_alter(&$items, $task) { + if (variable_get('page_manager_node_view_disabled', TRUE)) { + return; + } + + // Override the node view handler for our purpose. + $callback = $items['node/%node']['page callback']; + if ($callback == 'node_page_view' || variable_get('page_manager_override_anyway', FALSE)) { + $items['node/%node']['page callback'] = 'page_manager_node_view'; + $items['node/%node']['file path'] = $task['path']; + $items['node/%node']['file'] = $task['file']; + } + else { + // automatically disable this task if it cannot be enabled. + variable_set('page_manager_node_view_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_node_view'])) { + drupal_set_message(t('Page manager module is unable to enable node/%node because some other module already has overridden with %callback.', array('%callback' => $callback)), 'error'); + } + } + + // @todo override node revision handler as well? +} + +/** + * Entry point for our overridden node view. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * node view, which is node_page_view(). + */ +function page_manager_node_view($node) { + // Load my task plugin + $task = page_manager_get_task('node_view'); + + // Load the node into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + + // We need to mimic Drupal's behavior of setting the node title here. + drupal_set_title(check_plain($node->title)); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($node)); + + $output = ctools_context_handler_render($task, '', $contexts, array($node->nid)); + if ($output !== FALSE) { + node_tag_new($node->nid); + return $output; + } + + $function = 'node_page_view'; + foreach (module_implements('page_manager_override') as $module) { + $call = $module . '_page_manager_override'; + if (($rc = $call('node_view')) && function_exists($rc)) { + $function = $rc; + break; + } + } + + // Otherwise, fall back. + return $function($node); +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the node view and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function page_manager_node_view_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'node', + 'identifier' => t('Node being viewed'), + 'id' => 1, + 'name' => 'nid', + 'settings' => array(), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function page_manager_node_view_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(page_manager_node_view_get_arguments($task, $subtask_id)); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_node_view_enable($cache, $status) { + variable_set('page_manager_node_view_disabled', $status); + + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_node_view'] = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/page.admin.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/page.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..9d292f0787d7f18d57d55e98eb667960c26f3d74 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/page.admin.inc @@ -0,0 +1,1494 @@ +<?php + +/** + * @file + * Administrative functions for the page subtasks. + * + * These are attached to the menu system in page.inc via the hook_menu + * delegation. They are included here so that this code is loaded + * only when needed. + */ + +/** + * Delegated implementation of hook_menu(). + */ +function page_manager_page_menu(&$items, $task) { + // Set up access permissions. + $access_callback = isset($task['admin access callback']) ? $task['admin access callback'] : 'user_access'; + $access_arguments = isset($task['admin access arguments']) ? $task['admin access arguments'] : array('administer page manager'); + + $base = array( + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'file' => 'plugins/tasks/page.admin.inc', + ); + + $items['admin/build/pages/add'] = array( + 'title' => 'Add custom page', + 'page callback' => 'page_manager_page_add_subtask', + 'page arguments' => array(), + 'type' => MENU_LOCAL_TASK, + ) + $base; + + $items['admin/build/pages/import'] = array( + 'title' => 'Import page', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('page_manager_page_import_subtask', 'page'), + 'type' => MENU_LOCAL_TASK, + ) + $base; + if ($access_callback == 'user_access') { + $items['admin/build/pages/import']['access callback'] = 'ctools_access_multiperm'; + $items['admin/build/pages/import']['access arguments'][] = 'use PHP for block visibility'; + } + + // AJAX callbacks for argument modal. + $items['admin/build/pages/argument'] = array( + 'page callback' => 'page_manager_page_subtask_argument_ajax', + 'type' => MENU_CALLBACK, + ) + $base; + + // Add menu entries for each subtask + foreach (page_manager_page_load_all() as $subtask_id => $subtask) { + if (!empty($subtask->disabled)) { + continue; + } + + if (!isset($subtask->access['type'])) { + $subtask->access['type'] = 'none'; + } + if (!isset($subtask->access['settings'])) { + $subtask->access['settings'] = NULL; + } + + $path = array(); + $page_arguments = array($subtask_id); + $access_arguments = array($subtask->access); + $load_arguments = array($subtask_id, '%index', '%map'); + + // Replace named placeholders with our own placeholder to load contexts. + $position = 0; + + foreach (explode('/', $subtask->path) as $bit) { + // Remove things like double slashes completely. + if (!isset($bit) || $bit === '') { + continue; + } + + if ($bit[0] == '%' && $bit != '%') { + $placeholder = '%pm_arg'; + + // Chop off that %. + $name = substr($bit, 1); + + // Check to see if the argument plugin wants to use a different + // placholder. This will allow to_args. + if (!empty($subtask->arguments[$name])) { + ctools_include('context'); + if (!empty($subtask->arguments[$name]['name'])) { + $plugin = ctools_get_argument($subtask->arguments[$name]['name']); + if (isset($plugin['path placeholder'])) { + if (function_exists($plugin['path placeholder'])) { + $placeholder = $plugin['path placeholder']($subtask->arguments[$name]); + } + else { + $placeholder = $plugin['path placeholder']; + } + } + } + } + // If an argument, swap it out with our argument loader and make sure + // the argument gets passed through to the page callback. + $path[] = $placeholder; + $page_arguments[] = $position; + $access_arguments[] = $position; + } + else if ($bit[0] != '!') { + $path[] = $bit; + } + + // Increment position. We do it like this to skip empty items that + // could happen from erroneous paths like: this///that + $position++; + } + + $menu_path = implode('/', $path); + + $items[$menu_path] = page_manager_page_menu_item($task, $subtask->menu, $access_arguments, $page_arguments, $load_arguments); + + // Add a parent menu item if one is configured. + if (isset($subtask->menu['type']) && $subtask->menu['type'] == 'default tab' && $subtask->menu['parent']['type'] != 'none') { + array_pop($path); + $parent_path = implode('/', $path); + $items[$parent_path] = page_manager_page_menu_item($task, $subtask->menu['parent'], $access_arguments, $page_arguments, $load_arguments); + } + } +} + +/** + * Create a menu item for page manager pages. + * + * @param $menu + * The configuration to use. It will contain a type, and depending on the + * type may also contain weight, title and name. These are presumed to have + * been configured from the UI. + * @param $access_arguments + * Arguments that go with ctools_access_menu; it should be loaded with + * the access plugin type, settings, and positions of any arguments that + * may produce contexts. + * @param $page_arguments + * This should be seeded with the subtask name for easy loading and like + * the access arguments above should contain positions of arguments so + * that the menu system passes contexts through. + * @param $load_arguments + * Arguments to send to the arg loader; should be the subtask id and '%index'. + */ +function page_manager_page_menu_item($task, $menu, $access_arguments, $page_arguments, $load_arguments) { + $item = array( + 'access callback' => 'ctools_access_menu', + 'access arguments' => $access_arguments, + 'page callback' => 'page_manager_page_execute', + 'page arguments' => $page_arguments, + 'load arguments' => $load_arguments, + 'file' => 'plugins/tasks/page.inc', + ); + + if (isset($menu['title'])) { + $item['title'] = $menu['title']; + } + if (isset($menu['weight'])) { + $item['weight'] = $menu['weight']; + } + + if (empty($menu['type'])) { + $menu['type'] = 'none'; + } + + switch ($menu['type']) { + case 'none': + default: + $item['type'] = MENU_CALLBACK; + break; + + case 'normal': + $item['type'] = MENU_NORMAL_ITEM; + // Insert item into the proper menu + $item['menu_name'] = $menu['name']; + break; + + case 'tab': + $item['type'] = MENU_LOCAL_TASK; + break; + + case 'default tab': + $item['type'] = MENU_DEFAULT_LOCAL_TASK; + break; + } + + return $item; +} + +/** + * Page callback to add a subtask. + */ +function page_manager_page_add_subtask($task_name = NULL, $step = NULL) { + ctools_include('context'); + $task = page_manager_get_task('page'); + $task_handler_plugins = page_manager_get_task_handler_plugins($task); + if (empty($task_handler_plugins)) { + drupal_set_message(t('There are currently no variants available and a page may not be added. Perhaps you need to install the Panels module to get a variant?'), 'error'); + return ' '; + } + + $form_info = array( + 'id' => 'page_manager_add_page', + 'show trail' => TRUE, + 'show back' => TRUE, + 'show return' => FALSE, + 'next callback' => 'page_manager_page_add_subtask_next', + 'finish callback' => 'page_manager_page_add_subtask_finish', + 'return callback' => 'page_manager_page_add_subtask_finish', + 'cancel callback' => 'page_manager_page_add_subtask_cancel', + 'add order' => array( + 'basic' => t('Basic settings'), + 'argument' => t('Argument settings'), + 'access' => t('Access control'), + 'menu' => t('Menu settings'), + ), + 'forms' => array( + 'basic' => array( + 'form id' => 'page_manager_page_form_basic', + ), + 'access' => array( + 'form id' => 'page_manager_page_form_access', + ), + 'menu' => array( + 'form id' => 'page_manager_page_form_menu', + ), + 'argument' => array( + 'form id' => 'page_manager_page_form_argument', + ), + ), + ); + + if ($task_name) { + $page = page_manager_get_page_cache($task_name); + if (empty($page)) { + return drupal_not_found(); + } + + $form_info['path'] = "admin/build/pages/add/$task_name/%step"; + } + else { + $new_page = page_manager_page_new(); + $new_page->name = NULL; + + $page = new stdClass(); + page_manager_page_new_page_cache($new_page, $page); + $form_info['path'] = 'admin/build/pages/add/%task_name/%step'; + } + + if ($step && $step != 'basic') { + $handler_plugin = page_manager_get_task_handler($page->handler); + + $form_info['forms'] += $handler_plugin['forms']; + + if (isset($page->forms)) { + foreach ($page->forms as $id) { + if (isset($form_info['add order'][$id])) { + $form_info['order'][$id] = $form_info['add order'][$id]; + } + else if (isset($handler_plugin['add features'][$id])) { + $form_info['order'][$id] = $handler_plugin['add features'][$id]; + } + else if (isset($handler_plugin['required forms'][$id])) { + $form_info['order'][$id] = $handler_plugin['required forms'][$id]; + } + } + } + else { + $form_info['order'] = $form_info['add order']; + } + + // This means we just submitted our form from the default list + // of steps, which we've traded in for a newly generated list of + // steps above. We need to translate this 'next' step into what + // our questions determined would be next. + if ($step == 'next') { + $keys = array_keys($form_info['order']); + // get rid of 'basic' from the list of forms. + array_shift($keys); + $step = array_shift($keys); + + // If $step == 'basic' at this point, we were not presented with any + // additional forms at all. Let's just save and go! + if ($step == 'basic') { + page_manager_save_page_cache($page); + // Redirect to the new page's task handler editor. + drupal_goto(page_manager_edit_url($page->task_name)); + } + } + } + else { + $form_info['show trail'] = FALSE; + $form_info['order'] = array( + 'basic' => t('Basic settings'), + 'next' => t('A meaningless second page'), + ); + } + + ctools_include('wizard'); + $form_state = array( + 'task' => $task, + 'subtask' => $page->subtask, + 'page' => &$page, + 'type' => 'add', + 'task_id' => 'page', + 'task_name' => $page->task_name, + 'creating' => TRUE, + ); + + if (!empty($page->handlers)) { + $keys = array_keys($page->handlers); + $key = array_shift($keys); + $form_state['handler'] = &$page->handlers[$key]; + $form_state['handler_id'] = $key; + } + + $output = ctools_wizard_multistep_form($form_info, $step, $form_state); + + if (!$output) { + // redirect. + drupal_redirect_form(array(), $form_state['redirect']); + } + + return $output; +} + +/** + * Callback generated when the add page process is finished. + */ +function page_manager_page_add_subtask_finish(&$form_state) { + $page = &$form_state['page']; + // Update the cache with changes. + page_manager_set_page_cache($page); + + $handler = $form_state['handler']; + $handler_plugin = page_manager_get_task_handler($handler->handler); + + // Redirect to the new page's task handler editor. + if (isset($handler_plugin['add finish'])) { + $form_state['redirect'] = page_manager_edit_url($page->task_name, array('handlers', $handler->name, $handler_plugin['add finish'])); + } + else { + $form_state['redirect'] = page_manager_edit_url($page->task_name); + } + return; +} + +/** + * Callback generated when the 'next' button is clicked. + * + * All we do here is store the cache. + */ +function page_manager_page_add_subtask_next(&$form_state) { + if (empty($form_state['task_name']) || $form_state['task_name'] == 'page') { + // We may not have known the path to go next, because we didn't yet know the + // task name. This fixes that. + $form_state['form_info']['path'] = str_replace('%task_name', $form_state['page']->task_name, $form_state['form_info']['path']); + + $form_state['redirect'] = ctools_wizard_get_path($form_state['form_info'], $form_state['clicked_button']['#next']); + } + + // Update the cache with changes. + page_manager_set_page_cache($form_state['page']); +} + +/** + * Callback generated when the 'cancel' button is clicked. + * + * All we do here is clear the cache. + */ +function page_manager_page_add_subtask_cancel(&$form_state) { + // Wipe all our stored changes. + if (isset($form_state['page']->task_name)) { + page_manager_clear_page_cache($form_state['page']->task_name); + } +} + +/** + * Basic settings form for a page manager page. + */ +function page_manager_page_form_basic(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + $task = $form_state['task']; + + $form['admin_title'] = array( + '#type' => 'textfield', + '#title' => t('Administrative title'), + '#description' => t('The name of this page. This will appear in the administrative interface to easily identify it.'), + '#default_value' => $page->admin_title, + ); + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Machine name'), + '#description' => t('The machine readable name of this page. It must be unique, and it must contain only alphanumeric characters and underscores. Once created, you will not be able to change this value!'), + '#default_value' => $page->name, + ); + + if (isset($page->pid) || empty($form_state['creating'])) { + $form['name']['#disabled'] = TRUE; + $form['name']['#value'] = $page->name; + } + + $form['admin_description'] = array( + '#type' => 'textarea', + '#title' => t('Administrative description'), + '#description' => t('A description of what this page is, does or is for, for administrative use.'), + '#default_value' => $page->admin_description, + ); + + // path + $form['path'] = array( + '#type' => 'textfield', + '#title' => t('Path'), + '#description' => t('The URL path to get to this page. You may create named placeholders for variable parts of the path by using %name for required elements and !name for optional elements. For example: "node/%node/foo", "forum/%forum" or "dashboard/!input". These named placeholders can be turned into contexts on the arguments form.'), + '#default_value' => $page->path, + '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='), + ); + + $frontpage = variable_get('site_frontpage', 'node'); + + $path = array(); + if ($page->path) { + foreach (explode('/', $page->path) as $bit) { + if ($bit[0] != '!') { + $path[] = $bit; + } + } + } + + $path = implode('/', $path); + + if (empty($path) || $path != $frontpage) { + $form['frontpage'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($page->make_frontpage), + '#title' => t('Make this your site home page.'), + '#description' => t('To set this panel as your home page you must create a unique path name with no % placeholders in the path. The site home page is currently set to %homepage on the !siteinfo configuration form.', array('!siteinfo' => l('Site Information', 'admin/settings/site-information'), '%homepage' => '/' . $frontpage)), + ); + } + else if ($path == $frontpage) { + $form['frontpage_markup'] = array( + '#value' => '<b>' . t('This page is currently set to be your site home page. This can be modified on the !siteinfo configuration form.', array('!siteinfo' => l('Site Information', 'admin/settings/site-information'))) . '</b>', + ); + + $form['frontpage'] = array( + '#type' => 'value', + '#value' => TRUE, + ); + } + + if (!isset($page->pid) && !empty($form_state['creating'])) { + $features['default'] = array( + 'access' => t('Access control'), + 'menu' => t('Visible menu item'), + ); + + module_load_include('inc', 'page_manager', 'page_manager.admin'); + page_manager_handler_add_form($form, $form_state, $features); + } + +} + +function page_manager_page_form_basic_validate_filter($value) { + return $value === -1; +} + +/** + * Validate the basic form. + */ +function page_manager_page_form_basic_validate(&$form, &$form_state) { + // Ensure path is unused by other pages. + $page = $form_state['page']->subtask['subtask']; + $name = !empty($form_state['values']['name']) ? $form_state['values']['name'] : $page->name; + if (empty($name)) { + form_error($form['name'], t('Name is required.')); + } + + // If this is new, make sure the name is unique: + if (empty($page->name)) { + $test = page_manager_page_load($name); + if ($test) { + form_error($form['name'], t('That name is used by another page: @page', array('@page' => $test->admin_title))); + } + + // Ensure name fits the rules: + if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) { + form_error($form['name'], t('Page name must be alphanumeric or underscores only.')); + } + } + + $pages = page_manager_page_load_all(); + foreach ($pages as $test) { + if ($test->name != $name && $test->path == $form_state['values']['path'] && empty($test->disabled)) { + form_error($form['path'], t('That path is used by another page: @page', array('@page' => $test->admin_title))); + } + } + + // Ensure path is unused by things NOT pages. We do the double check because + // we're checking against our page callback. + $path = array(); + if (empty($form_state['values']['path'])) { + form_error($form['path'], t('Path is required.')); + // stop processing here if there is no path. + return; + } + + $found = FALSE; + $error = FALSE; + foreach (explode('/', $form_state['values']['path']) as $position => $bit) { + if (!isset($bit) || $bit === '') { + continue; + } + + if ($bit == '%' || $bit == '!') { + form_error($form['path'], t('You cannot have an unnamed placeholder (% or ! by itself). Please name your placeholder by adding a short piece of descriptive text to the % or !, such as %user or %node.')); + } + + if ($bit[0] == '%') { + if ($found) { + form_error($form['path'], t('You cannot have a dynamic path element after an optional path element.')); + } + + if ($position == 0) { + form_error($form['path'], t('The first element in a path may not be dynamic.')); + } + + $path[] = '%'; + } + else if ($bit[0] == '!') { + $found = TRUE; + } + else { + if ($found) { + form_error($form['path'], t('You cannot have a static path element after an optional path element.')); + } + $path[] = $bit; + } + } + + // Check to see if something that isn't a page manager page is using the path. + $path = implode('/', $path); + $result = db_query("SELECT * FROM {menu_router} WHERE path = '%s'", $path); + while ($router = db_fetch_object($result)) { + if ($router->page_callback != 'page_manager_page_execute') { + form_error($form['path'], t('That path is already in use. This system cannot override existing paths.')); + } + } + + // Ensure the path is not already an alias to something else. + if (strpos($path, '%') === FALSE) { + $result = db_query("SELECT src, dst FROM {url_alias} WHERE dst = '%s'", $path); + if ($alias = db_fetch_object($result)) { + form_error($form['path'], t('That path is currently assigned to be an alias for @alias. This system cannot override existing aliases.', array('@alias' => $alias->src))); + } + } + else { + if (!empty($form_state['values']['frontpage'])) { + form_error($form['path'], t('You cannot make this page your site home page if it uses % placeholders.')); + } + } + + // Ensure path is properly formed. + $args = page_manager_page_get_named_arguments($form_state['values']['path']); + if ($invalid_args = array_filter($args, 'page_manager_page_form_basic_validate_filter')) { + foreach ($invalid_args as $arg => $position) { + form_error($form['path'], t('Duplicated argument %arg', array('%arg' => $arg))); + } + } + + if (isset($args['%'])) { + form_error($form['path'], t('Invalid arg <em>%</em>. All arguments must be named with keywords.')); + } + + $form_state['arguments'] = $args; +} + +/** + * Store the values from the basic settings form. + */ +function page_manager_page_form_basic_submit(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + $cache = &$form_state['page']; + + // If this is a new thing, then we have to do a bunch of setup to create + // the cache record with the right ID and some basic data that we could + // not know until we asked the user some questions. + if (!isset($page->pid) && !empty($form_state['creating'])) { + // Update the data with our new name. + $page->name = $form_state['values']['name']; + $form_state['page']->task_name = page_manager_make_task_name($form_state['task_id'], $page->name); + $cache->handler = $form_state['values']['handler']; + $cache->subtask_id = $page->name; + $plugin = page_manager_get_task_handler($cache->handler); + + // If they created and went back, there might be old, dead handlers + // that are not going to be added. + // + // Remove them: + $cache->handlers = array(); + $cache->handler_info = array(); + + // Create a new handler. + $handler = page_manager_new_task_handler($plugin); + $title = !empty($form_state['values']['title']) ? $form_state['values']['title'] : $plugin['title']; + page_manager_handler_add_to_page($cache, $handler, $title); + + // Figure out which forms to present them with + $cache->forms = array(); + $cache->forms[] = 'basic'; // This one is always there. + if (!empty($form_state['arguments'])) { + $cache->forms[] = 'argument'; + } + + $features = $form_state['values']['features']; + $cache->forms = array_merge($cache->forms, array_keys(array_filter($features['default']))); + if (isset($features[$form_state['values']['handler']])) { + $cache->forms = array_merge($cache->forms, array_keys(array_filter($features[$form_state['values']['handler']]))); + } + + if (isset($plugin['required forms'])) { + $cache->forms = array_merge($cache->forms, array_keys($plugin['required forms'])); + } + } + + $page->admin_title = $form_state['values']['admin_title']; + $cache->subtask['admin title'] = check_plain($form_state['values']['admin_title']); + + $page->admin_description = $form_state['values']['admin_description']; + $cache->subtask['admin description'] = filter_xss_admin($form_state['values']['admin_description']); + + if ($page->path != $form_state['values']['path']) { + $page->path = $form_state['values']['path']; + page_manager_page_recalculate_arguments($page); + $cache->path_changed = TRUE; + } + + $page->make_frontpage = !empty($form_state['values']['frontpage']); +} + +/** + * Form to handle menu item controls. + */ +function page_manager_page_form_menu(&$form, &$form_state) { + ctools_include('dependent'); + $form['menu'] = array( + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + + $menu = $form_state['page']->subtask['subtask']->menu; + if (empty($menu)) { + $menu = array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + 'name' => 'navigation', + 'parent' => array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + 'name' => 'navigation', + ), + ); + } + + $form['menu']['type'] = array( + '#title' => t('Type'), + '#type' => 'radios', + '#options' => array( + 'none' => t('No menu entry'), + 'normal' => t('Normal menu entry'), + 'tab' => t('Menu tab'), + 'default tab' => t('Default menu tab'), + ), + '#default_value' => $menu['type'], + ); + + $form['menu']['title'] = array( + '#title' => t('Title'), + '#type' => 'textfield', + '#default_value' => $menu['title'], + '#description' => t('If set to normal or tab, enter the text to use for the menu item.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('normal', 'tab', 'default tab')), + ); + + list($major, $minor) = explode('.', VERSION, 2); + + $form['menu']['name-warning'] = array( + '#type' => 'markup', + '#prefix' => '<div class="warning">', + '#value' => t("Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url.", array('!url' => l('drupal.org', 'http://drupal.org/project/Drupal+project'))), + '#suffix' => '</div>', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('normal')), + '#access' => ($minor < 5), + ); + + // Only display the menu selector if menu module is enabled. + if (module_exists('menu')) { + $form['menu']['name'] = array( + '#title' => t('Menu'), + '#type' => 'select', + '#options' => menu_get_menus(), + '#default_value' => $menu['name'], + '#description' => t('Insert item into an available menu.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('normal')), + ); + } + else { + $form['menu']['name'] = array( + '#type' => 'value', + '#value' => $menu['name'], + ); + $form['menu']['markup'] = array( + '#value' => t('Menu selection requires the activation of menu module.'), + ); + } + $form['menu']['weight'] = array( + '#title' => t('Weight'), + '#type' => 'textfield', + '#default_value' => isset($menu['weight']) ? $menu['weight'] : 0, + '#description' => t('The lower the weight the higher/further left it will appear.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('normal', 'tab', 'default tab')), + ); + + $form['menu']['parent']['type'] = array( + '#prefix' => '<div id="edit-menu-parent-type-wrapper">', + '#suffix' => '</div>', + '#title' => t('Parent menu item'), + '#type' => 'radios', + '#options' => array('none' => t('Already exists'), 'normal' => t('Normal menu item'), 'tab' => t('Menu tab')), + '#default_value' => $menu['parent']['type'], + '#description' => t('When providing a menu item as a default tab, Drupal needs to know what the parent menu item of that tab will be. Sometimes the parent will already exist, but other times you will need to have one created. The path of a parent item will always be the same path with the last part left off. i.e, if the path to this view is <em>foo/bar/baz</em>, the parent path would be <em>foo/bar</em>.'), + '#process' => array('expand_radios', 'ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('default tab')), + ); + $form['menu']['parent']['title'] = array( + '#title' => t('Parent item title'), + '#type' => 'textfield', + '#default_value' => $menu['parent']['title'], + '#description' => t('If creating a parent menu item, enter the title of the item.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('default tab'), 'radio:menu[parent][type]' => array('normal', 'tab')), + '#dependency_count' => 2, + ); + // Only display the menu selector if menu module is enabled. + if (module_exists('menu')) { + $form['menu']['parent']['name'] = array( + '#title' => t('Parent item menu'), + '#type' => 'select', + '#options' => menu_get_menus(), + '#default_value' => $menu['parent']['name'], + '#description' => t('Insert item into an available menu.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('default tab'), 'radio:menu[parent][type]' => array('normal')), + '#dependency_count' => 2, + ); + } + else { + $form['menu']['parent']['name'] = array( + '#type' => 'value', + '#value' => $menu['parent']['name'], + ); + } + $form['menu']['parent']['weight'] = array( + '#title' => t('Tab weight'), + '#type' => 'textfield', + '#default_value' => $menu['parent']['weight'], + '#size' => 5, + '#description' => t('If the parent menu item is a tab, enter the weight of the tab. The lower the number, the more to the left it will be.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('default tab'), 'radio:menu[parent][type]' => array('tab')), + '#dependency_count' => 2, + ); +} + +/** + * Validate handler for the menu form for add/edit page task. + */ +function page_manager_page_form_menu_validate(&$form, &$form_state) { + // If setting a 'normal' menu entry, make sure that any placeholders + // support the to_arg stuff. + + if ($form_state['values']['menu']['type'] == 'normal') { + $page = $form_state['page']->subtask['subtask']; + + foreach (explode('/', $page->path) as $bit) { + if (!isset($bit) || $bit === '') { + continue; + } + + if ($bit[0] == '%') { + // Chop off that %. + $name = substr($bit, 1); + + // Check to see if the argument plugin allows to arg: + if (!empty($page->arguments[$name])) { + ctools_include('context'); + $plugin = ctools_get_argument($page->arguments[$name]['name']); + if (!empty($plugin['path placeholder to_arg'])) { + continue; + } + } + + form_error($form['menu']['type'], t('Paths with non optional placeholders cannot be used as normal menu items unless the selected argument handler provides a default argument to use for the menu item.')); + return; + } + } + } +} + +/** + * Submit handler for the menu form for add/edit page task. + */ +function page_manager_page_form_menu_submit(&$form, &$form_state) { + $form_state['page']->subtask['subtask']->menu = $form_state['values']['menu']; + $form_state['page']->path_changed = TRUE; +} + +/** + * Form to handle menu item controls. + */ +function page_manager_page_form_access(&$form, &$form_state) { + ctools_include('context'); + $form_state['module'] = 'page_manager_page'; + $form_state['callback argument'] = $form_state['page']->task_name; + $form_state['access'] = $form_state['page']->subtask['subtask']->access; + $form_state['no buttons'] = TRUE; + $form_state['contexts'] = array(); + + // Load contexts based on argument data: + if ($arguments = _page_manager_page_get_arguments($form_state['page']->subtask['subtask'])) { + $form_state['contexts'] = ctools_context_get_placeholders_from_argument($arguments); + } + + ctools_include('context-access-admin'); + $form = array_merge($form, ctools_access_admin_form($form_state)); +} + +/** + * Submit handler to deal with access control changes. + */ +function page_manager_page_form_access_submit(&$form, &$form_state) { + $form_state['page']->subtask['subtask']->access['logic'] = $form_state['values']['logic']; + $form_state['page']->path_changed = TRUE; +} + +/** + * Form to handle assigning argument handlers to named arguments. + */ +function page_manager_page_form_argument(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + $path = $page->path; + + $arguments = page_manager_page_get_named_arguments($path); + + $form['table'] = array( + '#theme' => 'page_manager_page_form_argument_table', + '#page-manager-path' => $path, + 'argument' => array(), + ); + + $task_name = $form_state['page']->task_name; + foreach ($arguments as $keyword => $position) { + $conf = array(); + + if (isset($page->temporary_arguments[$keyword]) && !empty($form_state['allow temp'])) { + $conf = $page->temporary_arguments[$keyword]; + } + else if (isset($page->arguments[$keyword])) { + $conf = $page->arguments[$keyword]; + } + + $context = t('No context assigned'); + + $plugin = array(); + if ($conf && isset($conf['name'])) { + ctools_include('context'); + $plugin = ctools_get_argument($conf['name']); + + if (isset($plugin['title'])) { + $context = $plugin['title']; + } + } + + $form['table']['argument'][$keyword]['#keyword'] = $keyword; + $form['table']['argument'][$keyword]['#position'] = $position; + $form['table']['argument'][$keyword]['#context'] = $context; + + // The URL for this ajax button + $form['table']['argument'][$keyword]['change-url'] = array( + '#attributes' => array('class' => "page-manager-context-$keyword-change-url"), + '#type' => 'hidden', + '#value' => url("admin/build/pages/argument/change/$task_name/$keyword", array('absolute' => TRUE)), + ); + $form['table']['argument'][$keyword]['change'] = array( + '#type' => 'submit', + '#value' => t('Change'), + '#attributes' => array('class' => 'ctools-use-modal'), + '#id' => "page-manager-context-$keyword-change", + ); + + $form['table']['argument'][$keyword]['settings'] = array(); + + // Only show the button if this has a settings form available: + if (!empty($plugin)) { + // The URL for this ajax button + $form['table']['argument'][$keyword]['settings-url'] = array( + '#attributes' => array('class' => "page-manager-context-$keyword-settings-url"), + '#type' => 'hidden', + '#value' => url("admin/build/pages/argument/settings/$task_name/$keyword", array('absolute' => TRUE)), + ); + $form['table']['argument'][$keyword]['settings'] = array( + '#type' => 'submit', + '#value' => t('Settings'), + '#attributes' => array('class' => 'ctools-use-modal'), + '#id' => "page-manager-context-$keyword-settings", + ); + } + } +} + +/** + * Theme the table for this form. + */ +function theme_page_manager_page_form_argument_table($form) { + $header = array( + array('data' => t('Argument'), 'class' => 'page-manager-argument'), + array('data' => t('Position in path'), 'class' => 'page-manager-position'), + array('data' => t('Context assigned'), 'class' => 'page-manager-context'), + array('data' => t('Operations'), 'class' => 'page-manager-operations'), + ); + + $rows = array(); + + ctools_include('modal'); + ctools_modal_add_js(); + foreach (element_children($form['argument']) as $key) { + $row = array(); + $row[] = '%' . check_plain($form['argument'][$key]['#keyword']); + $row[] = check_plain($form['argument'][$key]['#position']); + $row[] = $form['argument'][$key]['#context'] . ' ' . drupal_render($form['argument'][$key]['change']);; + $row[] = drupal_render($form['argument'][$key]['settings']) . drupal_render($form['argument'][$key]); + + $rows[] = array('data' => $row); + } + + if (!$rows) { + $rows[] = array(array('data' => t('The path %path has no arguments to configure.', array('%path' => $form['#page-manager-path'])), 'colspan' => 4)); + } + + $attributes = array( + 'id' => 'page-manager-argument-table', + ); + + $output = theme('table', $header, $rows, $attributes); + return $output; +} + +/** + * Ajax entry point to edit an item + */ +function page_manager_page_subtask_argument_ajax($step = NULL, $task_name = NULL, $keyword = NULL) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + ctools_include('wizard'); + + if (!$step) { + return ctools_ajax_render_error(); + } + + if (!$cache = page_manager_get_page_cache($task_name)) { + return ctools_ajax_render_error(t('Invalid object name.')); + } + + $page = &$cache->subtask['subtask']; + $path = $page->path; + $arguments = page_manager_page_get_named_arguments($path); + + // Load stored object from cache. + if (!isset($arguments[$keyword])) { + return ctools_ajax_render_error(t('Invalid keyword.')); + } + + // Set up wizard info + $form_info = array( + 'id' => 'page_manager_page_argument', + 'path' => "admin/build/pages/argument/%step/$task_name/$keyword", + 'show cancel' => TRUE, + 'next callback' => 'page_manager_page_argument_next', + 'finish callback' => 'page_manager_page_argument_finish', + 'cancel callback' => 'page_manager_page_argument_cancel', + 'order' => array( + 'change' => t('Change context type'), + 'settings' => t('Argument settings'), + ), + 'forms' => array( + 'change' => array( + 'title' => t('Change argument'), + 'form id' => 'page_manager_page_argument_form_change', + ), + 'settings' => array( + 'title' => t('Argument settings'), + 'form id' => 'page_manager_page_argument_form_settings', + ), + ), + ); + + $form_state = array( + 'page' => $cache, + 'keyword' => $keyword, + 'ajax' => TRUE, + 'modal' => TRUE, + 'commands' => array(), + ); + + // With 'modal' and 'ajax' true, rendering automatically happens here so + // we do nothing with the result. + $output = ctools_wizard_multistep_form($form_info, $step, $form_state); +} + +/** + * Callback generated when the add page process is finished. + */ +function page_manager_page_argument_finish(&$form_state) { + // Check to see if there are changes. + $page = &$form_state['page']->subtask['subtask']; + $keyword = &$form_state['keyword']; + + if (isset($page->temporary_arguments[$keyword])) { + $page->arguments[$keyword] = $page->temporary_arguments[$keyword]; + } + + if (isset($page->temporary_arguments)) { + unset($page->temporary_arguments); + } + + // Update the cache with changes. + page_manager_set_page_cache($form_state['page']); + + // Rerender the table so we can ajax it back in. + // Go directly to the form and retrieve it using a blank form and + // a clone of our current form state. This is an abbreviated + // drupal_get_form that is halted prior to render and is never + // fully processed, but is guaranteed to produce the same form we + // started with so we don't have to do crazy stuff to rerender + // just part of it. + + // @todo should there be a tool to do this? + + $clone_state = $form_state; + $clone_state['allow temp'] = TRUE; + $form = array(); + page_manager_page_form_argument($form, $clone_state); + drupal_prepare_form('page_manager_page_form_argument', $form, $clone_state); + $form['#post'] = array(); + $form = form_builder('page_manager_page_form_argument', $form, $clone_state); + + // Render just the table portion. + $output = drupal_render($form['table']); + $form_state['commands'][] = ctools_ajax_command_replace('#page-manager-argument-table', $output); +} + +/** + * Callback generated when the 'next' button is clicked. + * + * All we do here is store the cache. + */ +function page_manager_page_argument_next(&$form_state) { + // Update the cache with changes. + page_manager_set_page_cache($form_state['page']); +} + +/** + * Callback generated when the 'cancel' button is clicked. + * + * We might have some temporary data lying around. We must remove it. + */ +function page_manager_page_argument_cancel(&$form_state) { + $page = &$form_state['page']->subtask['subtask']; + if (isset($page->temporary_arguments)) { + unset($page->temporary_arguments); + // Update the cache with changes. + page_manager_set_page_cache($page); + } +} + +/** + * Basic settings form for a page manager page. + */ +function page_manager_page_argument_form_change(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + $keyword = &$form_state['keyword']; + + ctools_include('context'); + $plugins = ctools_get_arguments(); + + $options = array(); + foreach ($plugins as $id => $plugin) { + $options[$id] = $plugin['title']; + } + + asort($options); + + $options = array('' => t('No context selected')) + $options; + + $argument = ''; + if (isset($page->arguments[$keyword]) && isset($page->arguments[$keyword]['name'])) { + $argument = $page->arguments[$keyword]['name']; + } + + $form['argument'] = array( + '#type' => 'radios', + '#options' => $options, + '#default_value' => $argument, + ); +} + +/** + * Submit handler to change an argument. + */ +function page_manager_page_argument_form_change_submit(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + $keyword = &$form_state['keyword']; + $argument = $form_state['values']['argument']; + + // If the argument is not changing, we do not need to do anything. + if (isset($page->arguments[$keyword]['name']) && $page->arguments[$keyword]['name'] == $argument) { + // Set the task to cancel since no change means do nothing: + $form_state['clicked_button']['#wizard type'] = 'cancel'; + return; + } + + ctools_include('context'); + + // If switching to the no context, just wipe out the old data. + if (empty($argument)) { + $form_state['clicked_button']['#wizard type'] = 'finish'; + $page->temporary_arguments[$keyword] = array( + 'settings' => array(), + 'identifier' => t('No context'), + ); + return; + } + + $plugin = ctools_get_argument($argument); + + // Acquire defaults. + $settings = array(); + + if (isset($plugin['default'])) { + if (is_array($plugin['default'])) { + $settings = $plugin['default']; + } + else if (function_exists($plugin['default'])) { + $settings = $plugin['default'](); + } + } + + $id = ctools_context_next_id($page->arguments, $argument); + $title = isset($plugin['title']) ? $plugin['title'] : t('No context'); + + // Set the new argument in a temporary location. + $page->temporary_arguments[$keyword] = array( + 'id' => $id, + 'identifier' => $title . ($id > 1 ? ' ' . $id : ''), + 'name' => $argument, + 'settings' => $settings, + ); +} + +/** + * Basic settings form for a page manager page. + */ +function page_manager_page_argument_form_settings(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + $keyword = &$form_state['keyword']; + + if (isset($page->temporary_arguments[$keyword])) { + $conf = $page->temporary_arguments[$keyword]; + } + else if (isset($page->arguments[$keyword])) { + $conf = $page->temporary_arguments[$keyword] = $page->arguments[$keyword]; + } + + if (!isset($conf)) { + // This should be impossible and thus never seen. + $form['error'] = array('#value' => t('Error: missing argument.')); + return; + } + + ctools_include('context'); + $plugin = ctools_get_argument($conf['name']); + + $form['settings'] = array( + '#tree' => TRUE, + ); + + $form['identifier'] = array( + '#type' => 'textfield', + '#title' => t('Context identifier'), + '#description' => t('This is the title of the context used to identify it later in the administrative process. This will never be shown to a user.'), + '#default_value' => $conf['identifier'], + ); + + if (!$plugin) { + // This should be impossible and thus never seen. + $form['error'] = array('#value' => t('Error: missing or invalid argument plugin %argument.', array('%argument', $argument))); + return; + } + + if ($function = ctools_plugin_get_function($plugin, 'settings form')) { + $function($form, $form_state, $conf['settings']); + } + + $form_state['plugin'] = $plugin; +} + +/** + * Validate handler for argument settings. + */ +function page_manager_page_argument_form_settings_validate(&$form, &$form_state) { + if ($function = ctools_plugin_get_function($form_state['plugin'], 'settings form validate')) { + $function($form, $form_state); + } +} + +/** + * Submit handler for argument settings. + */ +function page_manager_page_argument_form_settings_submit(&$form, &$form_state) { + if ($function = ctools_plugin_get_function($form_state['plugin'], 'settings form submit')) { + $function($form, $form_state); + } + + $page = &$form_state['page']->subtask['subtask']; + $keyword = &$form_state['keyword']; + // Copy the form to our temporary location which will get moved again when + // finished. Yes, finished is always next but finish can happen from other + // locations so we funnel through that path rather than duplicate. + $page->temporary_arguments[$keyword]['identifier'] = $form_state['values']['identifier']; + if (isset($form_state['values']['settings'])) { + $page->temporary_arguments[$keyword]['settings'] = $form_state['values']['settings']; + } + else { + $page->temporary_arguments[$keyword]['settings'] = array(); + } +} + +/** + * Import a task handler from cut & paste + */ +function page_manager_page_import_subtask(&$form_state, $task_name) { + $form_state['task'] = page_manager_get_task($task_name); + + drupal_set_title(t('Import page')); + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Page name'), + '#description' => t('Enter the name to use for this page if it is different from the source page. Leave blank to use the original name of the page.'), + ); + + $form['path'] = array( + '#type' => 'textfield', + '#title' => t('Path'), + '#description' => t('Enter the path to use for this page if it is different from the source page. Leave blank to use the original path of the page.'), + ); + + $form['overwrite'] = array( + '#type' => 'checkbox', + '#title' => t('Allow overwrite of an existing page'), + '#description' => t('If the name you selected already exists in the database, this page will be allowed to overwrite the existing page.'), + ); + + $form['object'] = array( + '#type' => 'textarea', + '#title' => t('Paste page code here'), + '#rows' => 15, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Import'), + ); + return $form; +} + +/** + * Ensure we got a valid page. + */ +function page_manager_page_import_subtask_validate(&$form, &$form_state) { + ob_start(); + eval($form_state['values']['object']); + ob_end_clean(); + + if (!isset($page) || !is_object($page)) { + $errors = ob_get_contents(); + if (empty($errors)) { + $errors = t('No handler found.'); + } + form_error($form['object'], t('Unable to get a page from the import. Errors reported: @errors', array('@errors' => $errors))); + } + + if (empty($form_state['values']['name'])) { + $form_state['values']['name'] = $page->name; + } + + $task_name = page_manager_make_task_name('page', $form_state['values']['name']); + $form_state['cache'] = page_manager_get_page_cache($task_name); + + if ($form_state['cache'] && $form_state['cache']->locked) { + form_error($form['name'], t('That page name is in use and locked by another user. You must <a href="!break">break the lock</a> on that page before proceeding, or choose a different name.', array('!break' => url(page_manager_edit_url($task_name, array('actions', 'break-lock')))))); + return; + } + + if (empty($form_state['values']['path'])) { + $form_state['values']['path'] = $page->path; + } + + if (empty($form_state['values']['overwrite'])) { + $page->name = NULL; + } + + $form_state['page'] = new stdClass(); + $form_state['page']->subtask['subtask'] = $page; + page_manager_page_form_basic_validate($form, $form_state); +} + +/** + * Submit the import page to create the new page and redirect. + */ +function page_manager_page_import_subtask_submit($form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + $page->name = $form_state['values']['name']; + $page->path = $form_state['values']['path']; + + $task_name = page_manager_make_task_name('page', $page->name); + $cache = page_manager_get_page_cache($task_name); + if (!$cache) { + $cache = new stdClass(); + } + + page_manager_page_new_page_cache($page, $cache); + page_manager_set_page_cache($cache); + + $form_state['redirect'] = page_manager_edit_url($task_name); +} + +/** + * Entry point to export a page. + */ +function page_manager_page_form_export(&$form, &$form_state) { + $page = $form_state['page']->subtask['subtask']; + + $export = page_manager_page_export($page, $form_state['page']->handlers); + + $lines = substr_count($export, "\n"); + $form['code'] = array( + '#type' => 'textarea', + '#default_value' => $export, + '#rows' => $lines, + ); + + unset($form['buttons']); +} + +/** + * Entry point to clone a page. + */ +function page_manager_page_form_clone(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + + // This provides its own button because it does something totally different. + unset($form['buttons']); + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Page name'), + '#description' => t('Enter the name to the new page It must be unique and contain only alphanumeric characters and underscores.'), + ); + + $form['admin_title'] = array( + '#type' => 'textfield', + '#title' => t('Administrative title'), + '#description' => t('The name of this page. This will appear in the administrative interface to easily identify it.'), + '#default_value' => $page->admin_title, + ); + + // path + $form['path'] = array( + '#type' => 'textfield', + '#title' => t('Path'), + '#description' => t('The URL path to get to this page. You may create named placeholders for variable parts of the path by using %name for required elements and !name for optional elements. For example: "node/%node/foo", "forum/%forum" or "dashboard/!input". These named placeholders can be turned into contexts on the arguments form. You cannot use the same path as the original page.'), + '#default_value' => $page->path, + ); + + $form['handlers'] = array( + '#type' => 'checkbox', + '#title' => t('Clone variants'), + '#description' => t('If checked all variants associated with the page will be cloned as well. If not checked the page will be cloned without variants.'), + '#default_value' => TRUE, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Clone'), + ); +} + +/** + * Validate clone page form. + */ +function page_manager_page_form_clone_validate(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + + $page->old_name = $page->name; + $page->name = NULL; + page_manager_page_form_basic_validate($form, $form_state); +} + +/** + * submit clone page form. + * + * Load the page, change the name(s) to protect the innocent, and if + * requested, load all the task handlers so that they get saved properly too. + */ +function page_manager_page_form_clone_submit(&$form, &$form_state) { + $original = $form_state['page']->subtask['subtask']; + + $original->name = $form_state['values']['name']; + $original->admin_title = $form_state['values']['admin_title']; + $original->path = $form_state['values']['path']; + + $handlers = !empty($form_state['values']['handlers']) ? $form_state['page']->handlers : FALSE; + // Export the handler, which is a fantastic way to clean database IDs out of it. + $export = page_manager_page_export($original, $handlers); + ob_start(); + eval($export); + ob_end_clean(); + + $task_name = page_manager_make_task_name('page', $page->name); + $cache = new stdClass(); + + page_manager_page_new_page_cache($page, $cache); + page_manager_set_page_cache($cache); + + $form_state['redirect'] = page_manager_edit_url($task_name); +} + +/** + * Entry point to export a page. + */ +function page_manager_page_form_delete(&$form, &$form_state) { + $page = &$form_state['page']->subtask['subtask']; + + if ($page->type == t('Overridden')) { + $text = t('Reverting the page will delete the page that is in the database, reverting it to the original default page. Any changes you have made will be lost and cannot be recovered.'); + } + else { + $text = t('Are you sure you want to delete this page? Deleting a page cannot be undone.'); + } + $form['markup'] = array( + '#value' => '<p>' . $text . '</p>', + ); + + if (empty($form_state['page']->locked)) { + unset($form['buttons']); + $form['delete'] = array( + '#type' => 'submit', + '#value' => $page->type == t('Overridden') ? t('Revert') : t('Delete'), + ); + } +} + +/** + * Submit handler to delete a view. + */ +function page_manager_page_form_delete_submit(&$form, &$form_state) { + $page = $form_state['page']->subtask['subtask']; + page_manager_page_delete($page); + if ($page->type != t('Overridden')) { + $form_state['redirect'] = 'admin/build/pages'; + drupal_set_message(t('The page has been deleted.')); + } + else { + $form_state['redirect'] = page_manager_edit_url($form_state['page']->task_name, array('summary')); + drupal_set_message(t('The page has been reverted.')); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/page.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/page.inc new file mode 100644 index 0000000000000000000000000000000000000000..b60e275477242f38bf5401d7c69c935422ae5579 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/page.inc @@ -0,0 +1,778 @@ +<?php + +/** + * @file + * Handle the 'page' task, which creates pages with arbitrary tasks and lets + * handlers decide how they will be rendered. + * + * This creates subtasks and stores them in the page_manager_pages table. These + * are exportable objects, too. + * + * The render callback for this task type has $handler, $page, $contexts as + * parameters. + */ + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_page_page_manager_tasks() { + return array( + 'title' => t('Custom pages'), + 'description' => t('Administrator created pages that have a URL path, access control and entries in the Drupal menu system.'), + 'non-exportable' => TRUE, + 'subtasks' => TRUE, + 'subtask callback' => 'page_manager_page_subtask', + 'subtasks callback' => 'page_manager_page_subtasks', + 'save subtask callback' => 'page_manager_page_save_subtask', + 'hook menu' => array( + 'file' => 'page.admin.inc', + 'path' => drupal_get_path('module', 'page_manager') . '/plugins/tasks', + 'function' => 'page_manager_page_menu', + ), + 'hook theme' => 'page_manager_page_theme', + // page only items + 'task type' => 'page', + 'page operations' => array( + array( + 'title' => ' » ' . t('Create a new page'), + 'href' => 'admin/build/pages/add', + 'html' => TRUE, + ), + ), + 'columns' => array( + 'storage' => array( + 'label' => t('Storage'), + 'class' => 'page-manager-page-storage', + ), + ), + 'page type' => 'custom', + + // context only items + 'handler type' => 'context', + 'get arguments' => array( + 'file' => 'page.admin.inc', + 'path' => drupal_get_path('module', 'page_manager') . '/plugins/tasks', + 'function' => 'page_manager_page_get_arguments', + ), + 'get context placeholders' => 'page_manager_page_get_contexts', + 'access restrictions' => 'page_manager_page_access_restrictions', + 'uses handlers' => TRUE, + ); +} + +/** + * Task callback to get all subtasks. + * + * Return a list of all subtasks. + */ +function page_manager_page_subtasks($task) { + $pages = page_manager_page_load_all($task['name']); + $return = array(); + foreach ($pages as $name => $page) { + $return[$name] = page_manager_page_build_subtask($task, $page); + } + + return $return; +} + +/** + * Callback to return a single subtask. + */ +function page_manager_page_subtask($task, $subtask_id) { + $page = page_manager_page_load($subtask_id); + if ($page) { + return page_manager_page_build_subtask($task, $page); + } +} + +/** + * Call back from the administrative system to save a page. + * + * We get the $subtask as created by page_manager_page_build_subtask. + */ +function page_manager_page_save_subtask($subtask) { + $page = &$subtask['subtask']; + + // Ensure $page->arguments contains only real arguments: + $arguments = page_manager_page_get_named_arguments($page->path); + $args = array(); + foreach ($arguments as $keyword => $position) { + if (isset($page->arguments[$keyword])) { + $args[$keyword] = $page->arguments[$keyword]; + } + else { + $args[$keyword] = array( + 'id' => '', + 'identifier' => '', + 'argument' => '', + 'settings' => array(), + ); + } + } + page_manager_page_recalculate_arguments($page); + // Create a real object from the cache + page_manager_page_save($page); + + // Check to see if we should make this the site frontpage. + if (!empty($page->make_frontpage)) { + $path = array(); + foreach (explode('/', $page->path) as $bit) { + if ($bit[0] != '!') { + $path[] = $bit; + } + } + + $path = implode('/', $path); + $front = variable_get('site_frontpage', 'node'); + if ($path != $front) { + variable_set('site_frontpage', $path); + } + } +} + +/** + * Build a subtask array for a given page. + */ +function page_manager_page_build_subtask($task, $page) { + $operations = array(); + $operations['settings'] = array( + 'type' => 'group', + 'class' => 'operations-settings', + 'title' => t('Settings'), + 'children' => array(), + ); + + $settings = &$operations['settings']['children']; + + $settings['basic'] = array( + 'title' => t('Basic'), + 'description' => t('Edit name, path and other basic settings for the page.'), + 'form' => 'page_manager_page_form_basic', + ); + + $arguments = page_manager_page_get_named_arguments($page->path); + if ($arguments) { + $settings['argument'] = array( + 'title' => t('Arguments'), + 'description' => t('Set up contexts for the arguments on this page.'), + 'form' => 'page_manager_page_form_argument', + ); + } + + $settings['access'] = array( + 'title' => t('Access'), + 'description' => t('Control what users can access this page.'), + 'admin description' => t('Access rules are used to test if the page is accessible and any menu items associated with it are visible.'), + 'form' => 'page_manager_page_form_access', + ); + + $settings['menu'] = array( + 'title' => t('Menu'), + 'description' => t('Provide this page a visible menu or a menu tab.'), + 'form' => 'page_manager_page_form_menu', + ); + + $operations['actions']['children']['clone'] = array( + 'title' => t('Clone'), + 'description' => t('Make a copy of this page'), + 'form' => 'page_manager_page_form_clone', + ); + $operations['actions']['children']['export'] = array( + 'title' => t('Export'), + 'description' => t('Export this page as code that can be imported or embedded into a module.'), + 'form' => 'page_manager_page_form_export', + ); + if ($page->export_type == (EXPORT_IN_CODE | EXPORT_IN_DATABASE)) { + $operations['actions']['children']['delete'] = array( + 'title' => t('Revert'), + 'description' => t('Remove all changes to this page and revert to the version in code.'), + 'form' => 'page_manager_page_form_delete', + ); + } + else if ($page->export_type != EXPORT_IN_CODE) { + $operations['actions']['children']['delete'] = array( + 'title' => t('Delete'), + 'description' => t('Remove this page from your system completely.'), + 'form' => 'page_manager_page_form_delete', + ); + } + + $subtask = array( + 'name' => $page->name, + 'admin title' => check_plain($page->admin_title), + 'admin description' => filter_xss_admin($page->admin_description), + 'admin summary' => 'page_manager_page_admin_summary', + 'admin path' => $page->path, + 'admin type' => t('Custom'), + 'subtask' => $page, + 'operations' => $operations, + 'operations include' => array( + 'file' => 'page.admin.inc', + 'path' => drupal_get_path('module', 'page_manager') . '/plugins/tasks', + ), + 'single task' => empty($page->multiple), + 'row class' => empty($page->disabled) ? 'page-manager-enabled' : 'page-manager-disabled', + 'storage' => $page->type == t('Default') ? t('In code') : $page->type, + 'disabled' => !empty($page->disabled), + // This works for both enable AND disable + 'enable callback' => 'page_manager_page_enable', + ); + + // default handlers may appear from a default subtask. + if (isset($page->default_handlers)) { + $subtask['default handlers'] = $page->default_handlers; + } + return $subtask; +} + +/** + * Delegated implementation of hook_theme(). + */ +function page_manager_page_theme(&$items, $task) { + $base = array( + 'file' => 'page.admin.inc', + 'path' => drupal_get_path('module', 'page_manager') . '/plugins/tasks', + ); + $items['page_manager_page_form_argument_table'] = $base + array( + 'arguments' => array('form' => NULL), + ); + $items['page_manager_page_lock'] = $base + array( + 'arguments' => array('lock' => array(), 'task_name' => NULL), + ); + $items['page_manager_page_changed'] = $base + array( + 'arguments' => array(), + ); +} + +// -------------------------------------------------------------------------- +// Page execution functions + +/** + * Execute a page task. + * + * This is the callback to entries in the Drupal menu system created by the + * page task. + * + * @param $subtask_id + * The name of the page task used. + * @param ... + * A number of context objects as specified by the user when + * creating named arguments in the path. + */ +function page_manager_page_execute($subtask_id) { + $page = page_manager_page_load($subtask_id); + $task = page_manager_get_task($page->task); + $subtask = page_manager_get_task_subtask($task, $subtask_id); + + // Turn the contexts into a properly keyed array. + $contexts = array(); + $args = array(); + foreach (func_get_args() as $count => $arg) { + if (is_object($arg) && get_class($arg) == 'ctools_context') { + $contexts[$arg->id] = $arg; + $args[] = $arg->original_argument; + } + else if ($count) { + $args[] = $arg; + } + } + + $count = 0; + $names = page_manager_page_get_named_arguments($page->path); + $bits = explode('/', $page->path); + + if ($page->arguments) { + foreach ($page->arguments as $name => $argument) { + // Optional arguments must be converted to contexts too, if they exist. + if ($bits[$names[$name]][0] == '!') { + ctools_include('context'); + $argument['keyword'] = $name; + if (isset($args[$count])) { + // Hack: use a special argument config variable to learn if we need + // to use menu_tail style behavior: + if (empty($argument['settings']['use_tail'])) { + $value = $args[$count]; + } + else { + $value = implode('/', array_slice($args, $count)); + } + + $context = ctools_context_get_context_from_argument($argument, $value); + } + else { + // make sure there is a placeholder context for missing optional contexts. + $context = ctools_context_get_context_from_argument($argument, NULL, TRUE); + // Force the title to blank for replacements + } + if ($context) { + $contexts[$context->id] = $context; + } + } + $count++; + } + } + + // Add a fake tab for 'View' so that edit tabs can be added. + if (user_access('administer page manager') && (!isset($page->menu['type']) || in_array($page->menu['type'], array('tab', 'default tab')))) { + ctools_include('menu'); + ctools_menu_add_tab(array( + 'title' => t('View'), + 'href' => $_GET['q'], + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + )); + } + + + if ($function = ctools_plugin_get_function($task, 'page callback')) { + return call_user_func_array($function, array($page, $contexts, $args)); + } + + ctools_include('context-task-handler'); + $output = ctools_context_handler_render($task, $subtask, $contexts, $args); + if ($output === FALSE) { + return drupal_not_found(); + } + + return $output; +} + +// -------------------------------------------------------------------------- +// Context type callbacks + +/** + * Return a list of arguments used by this task. + */ +function page_manager_page_get_arguments($task, $subtask) { + return _page_manager_page_get_arguments($subtask['subtask']); +} + +function _page_manager_page_get_arguments($page) { + $arguments = array(); + if (!empty($page->arguments)) { + foreach ($page->arguments as $keyword => $argument) { + if (isset($argument['name'])) { + $argument['keyword'] = $keyword; + $arguments[$keyword] = $argument; + } + } + } + return $arguments; +} + +/** + * Get a group of context placeholders for the arguments. + */ +function page_manager_page_get_contexts($task, $subtask) { + ctools_include('context'); + return ctools_context_get_placeholders_from_argument(page_manager_page_get_arguments($task, $subtask)); +} + +/** + * Return a list of arguments used by this task. + */ +function page_manager_page_access_restrictions($task, $subtask, $contexts) { + $page = $subtask['subtask']; + return ctools_access_add_restrictions($page->access, $contexts); +} + +// -------------------------------------------------------------------------- +// Page task database info. + +/** + * Create a new page with defaults appropriately set from schema. + */ +function page_manager_page_new() { + ctools_include('export'); + return ctools_export_new_object('page_manager_pages'); +} + +/** + * Load a single page subtask. + */ +function page_manager_page_load($name) { + ctools_include('export'); + $result = ctools_export_load_object('page_manager_pages', 'names', array($name)); + if (isset($result[$name])) { + return $result[$name]; + } +} + +/** + * Load all page subtasks. + */ +function page_manager_page_load_all($task = NULL) { + ctools_include('export'); + + if (empty($task)) { + return ctools_export_load_object('page_manager_pages'); + } + else { + return ctools_export_load_object('page_manager_pages', 'conditions', array('task' => $task)); + } +} + +/** + * Write a page subtask to the database. + */ +function page_manager_page_save(&$page) { + $update = (isset($page->pid)) ? array('pid') : array(); + $task = page_manager_get_task($page->task); + + if ($function = ctools_plugin_get_function($task, 'save')) { + $function($page, $update); + } + drupal_write_record('page_manager_pages', $page, $update); + + // If this was a default page we may need to write default task + // handlers that we provided as well. + if (!$update && isset($page->default_handlers)) { + $handlers = page_manager_load_task_handlers(page_manager_get_task('page'), $page->name); + foreach ($page->default_handlers as $name => $handler) { + if (!isset($handlers[$name]) || !($handlers[$name]->export_type & EXPORT_IN_DATABASE)) { + // Make sure this is right, as exports can wander a bit. + $handler->subtask = $page->name; + page_manager_save_task_handler($handler); + } + } + } + return $page; +} + +/** + * Remove a page subtask. + */ +function page_manager_page_delete($page) { + $task = page_manager_get_task($page->task); + if ($function = ctools_plugin_get_function($task, 'delete')) { + $function($page); + } + if (!empty($task['uses handlers'])) { + $handlers = page_manager_load_task_handlers($task, $page->name); + foreach ($handlers as $handler) { + page_manager_delete_task_handler($handler); + } + } + db_query("DELETE FROM {page_manager_pages} WHERE name = '%s'", $page->name); + // Make sure that the cache is reset so that the menu rebuild does not + // rebuild this page again. + ctools_include('export'); + ctools_export_load_object_reset('page_manager_pages'); + menu_rebuild(); +} + +/** + * Export a page subtask. + */ +function page_manager_page_export($page, $with_handlers = FALSE, $indent = '') { + $task = page_manager_get_task($page->task); + $append = ''; + + if ($function = ctools_plugin_get_function($task, 'export')) { + $append = $function($page, $indent); + } + + ctools_include('export'); + $output = ctools_export_object('page_manager_pages', $page, $indent); + $output .= $append; + + if ($with_handlers) { + if (is_array($with_handlers)) { + $handlers = $with_handlers; + } + else { + $handlers = page_manager_load_task_handlers(page_manager_get_task('page'), $page->name); + } + $output .= $indent . '$page->default_handlers = array();' . "\n"; + foreach ($handlers as $handler) { + $output .= page_manager_export_task_handler($handler, $indent); + $output .= $indent . '$page->default_handlers[$handler->name] = $handler;' . "\n"; + } + } + return $output; +} + +/** + * Get a list of named arguments in a page manager path. + * + * @param $path + * A normal Drupal path. + * + * @return + * An array of % marked variable arguments, keyed by the argument's name. + * The value will be the position of the argument so that it can easily + * be found. Items with a position of -1 have multiple positions. + */ +function page_manager_page_get_named_arguments($path) { + $arguments = array(); + $bits = explode('/', $path); + foreach ($bits as $position => $bit) { + if ($bit && ($bit[0] == '%' || $bit[0] == '!')) { + // special handling for duplicate path items and substr to remove the % + $arguments[substr($bit, 1)] = isset($arguments[$bit]) ? -1 : $position; + } + } + + return $arguments; +} + +/** + * Load a context from an argument for a given page task. + * + * Helper function for pm_arg_load(), which is in page_manager.module because + * drupal's menu system does not allow loader functions to reside in separate + * files. + * + * @param $value + * The incoming argument value. + * @param $subtask + * The subtask id. + * @param $argument + * The numeric position of the argument in the path, counting from 0. + * + * @return + * A context item if one is configured, the argument if one is not, or + * FALSE if restricted or invalid. + */ +function _pm_arg_load($value, $subtask, $argument) { + $page = page_manager_page_load($subtask); + if (!$page) { + return FALSE; + } + + $path = explode('/', $page->path); + if (empty($path[$argument])) { + return FALSE; + } + + $keyword = substr($path[$argument], 1); + if (empty($page->arguments[$keyword])) { + return $value; + } + + $page->arguments[$keyword]['keyword'] = $keyword; + + ctools_include('context'); + $context = ctools_context_get_context_from_argument($page->arguments[$keyword], $value); + + // convert false equivalents to false. + return $context ? $context : FALSE; +} + +/** + * Provide a nice administrative summary of the page so an admin can see at a + * glance what this page does and how it is configured. + */ +function page_manager_page_admin_summary($task, $subtask) { + $task_name = page_manager_make_task_name($task['name'], $subtask['name']); + $page = $subtask['subtask']; + $output = ''; + + $rows = array(); + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Storage')), + array('class' => t('page-summary-data'), 'data' => $subtask['storage']), + array('class' => t('page-summary-operation'), 'data' => ''), + ); + + if (!empty($page->disabled)) { + $link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $page->name, 'actions', 'enable'))); + $text = t('Disabled'); + } + else { + $link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $page->name, 'actions', 'disable'))); + $text = t('Enabled'); + } + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Status')), + array('class' => t('page-summary-data'), 'data' => $text), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + + $path = array(); + foreach (explode('/', $page->path) as $bit) { + if ($bit[0] != '!') { + $path[] = $bit; + } + } + + $path = implode('/', $path); + $front = variable_get('site_frontpage', 'node'); + + $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'basic'))); + $message = ''; + if ($path == $front) { + $message = t('This is your site home page.'); + } + else if (!empty($page->make_frontpage)) { + $message = t('This page is set to become your site home page.'); + } + + if ($message) { + $rows[] = array( + array('class' => t('page-summary-data'), 'data' => $message, 'colspan' => 2), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + } + + if (strpos($path, '%') === FALSE) { + $path = l('/' . $page->path, $path); + } + else { + $path = '/' . $page->path; + } + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Path')), + array('class' => t('page-summary-data'), 'data' => $path), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + if (empty($access['plugins'])) { + $access['plugins'] = array(); + } + + $contexts = page_manager_page_get_contexts($task, $subtask); + $access = ctools_access_group_summary($page->access, $contexts); + if ($access) { + $access = t('Accessible only if @conditions.', array('@conditions' => $access)); + } + else { + $access = t('This page is publicly accessible.'); + } + + $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'access'))); + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Access')), + array('class' => t('page-summary-data'), 'data' => $access), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + $menu_options = array( + 'none' => t('No menu entry.'), + 'normal' => t('Normal menu entry.'), + 'tab' => t('Menu tab.'), + 'default tab' => t('Default menu tab.'), + ); + + if (!empty($page->menu)) { + $menu = $menu_options[$page->menu['type']]; + if ($page->menu['type'] != 'none') { + $menu .= ' ' . t('Title: %title.', array('%title' => $page->menu['title'])); + switch ($page->menu['type']) { + case 'default tab': + $menu .= ' ' . t('Parent title: %title.', array('%title' => $page->menu['parent']['title'])); + break; + case 'normal': + if (module_exists('menu')) { + $menus = menu_get_menus(); + $menu .= ' ' . t('Menu block: %title.', array('%title' => $menus[$page->menu['name']])); + } + break; + } + } + } + else { + $menu = t('No menu entry'); + } + + $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'menu'))); + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Menu')), + array('class' => t('page-summary-data'), 'data' => $menu), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + $output .= theme('table', array(), $rows, array('id' => 'page-manager-page-summary')); + return $output; +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_page_enable(&$cache, $status) { + $page = &$cache->subtask['subtask']; + ctools_include('export'); + ctools_export_set_object_status($page, $status); + + $page->disabled = FALSE; +} + +/** + * Recalculate the arguments when something like the path changes. + */ +function page_manager_page_recalculate_arguments(&$page) { + // Ensure $page->arguments contains only real arguments: + $arguments = page_manager_page_get_named_arguments($page->path); + $args = array(); + foreach ($arguments as $keyword => $position) { + if (isset($page->arguments[$keyword])) { + $args[$keyword] = $page->arguments[$keyword]; + } + else { + $args[$keyword] = array( + 'id' => '', + 'identifier' => '', + 'argument' => '', + 'settings' => array(), + ); + } + } + $page->arguments = $args; +} + +/** + * When adding or cloning a new page, this creates a new page cache + * and adds our page to it. + * + * This does not check to see if the existing cache is already locked. + * This must be done beforehand. + * + * @param &$page + * The page to create. + * @param &$cache + * The cache to use. If the cache has any existing task handlers, + * they will be marked for deletion. This may be a blank object. + */ +function page_manager_page_new_page_cache(&$page, &$cache) { + // Does a page already exist? If so, we are overwriting it so + // take its pid. + if (!empty($cache->subtask) && !empty($cache->subtask['subtask']) && !empty($cache->subtask['subtask']->pid)) { + $page->pid = $cache->subtask['subtask']->pid; + } + else { + $cache->new = TRUE; + } + + $cache->task_name = page_manager_make_task_name('page', $page->name); + $cache->task_id = 'page'; + $cache->task = page_manager_get_task('page'); + $cache->subtask_id = $page->name; + $page->export_type = EXPORT_IN_DATABASE; + $page->type = t('Normal'); + $cache->subtask = page_manager_page_build_subtask($cache->task, $page); + + if (isset($cache->handlers)) { + foreach($cache->handlers as $id => $handler) { + $cache->handler_info[$id]['changed'] = PAGE_MANAGER_CHANGED_DELETED; + } + } + else { + $cache->handlers = array(); + $cache->handler_info = array(); + } + + if (!empty($page->default_handlers)) { + foreach ($page->default_handlers as $id => $handler) { + page_manager_handler_add_to_page($cache, $handler); + } + } + + $cache->locked = FALSE; + $cache->changed = TRUE; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/poll.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/poll.inc new file mode 100644 index 0000000000000000000000000000000000000000..1dcb419079525b4c496d61326cc3a208b5a31009 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/poll.inc @@ -0,0 +1,104 @@ +<?php + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_poll_page_manager_tasks() { + if (!module_exists('poll')) { + return; + } + + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + + 'title' => t('All polls'), + 'admin title' => t('All polls'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for the polls at <em>/poll</em>. If no variant is selected, the default Drupal most recent polls will be shown.'), + 'admin path' => 'poll', + + // Menu hooks so that we can alter the node/%node menu entry to point to us. + 'hook menu alter' => 'page_manager_poll_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_poll_disabled', TRUE), + 'enable callback' => 'page_manager_poll_enable', + ); +} + +/** + * Callback defined by page_manager_poll_page_manager_tasks(). + * + * Alter the node edit input so that node edit comes to us rather than the + * normal node edit process. + */ +function page_manager_poll_menu_alter(&$items, $task) { + if (variable_get('page_manager_poll_disabled', TRUE)) { + return; + } + + $callback = $items['poll']['page callback']; + // Override the node edit handler for our purpose. + if ($callback == 'poll_page' || variable_get('page_manager_override_anyway', FALSE)) { + $items['poll']['page callback'] = 'page_manager_poll'; + $items['poll']['file path'] = $task['path']; + $items['poll']['file'] = $task['file']; + } + else { + variable_set('page_manager_poll_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_poll'])) { + drupal_set_message(t('Page manager module is unable to enable poll because some other module already has overridden with %callback.', array('%callback' => $callback)), 'warning'); + } + return; + } + +} + +/** + * Entry point for our overridden node edit. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * node edit, which is node_page_edit(). + */ +function page_manager_poll() { + // Load my task plugin + $task = page_manager_get_task('poll'); + + ctools_include('context'); + ctools_include('context-task-handler'); + $output = ctools_context_handler_render($task, '', array(), array()); + if ($output !== FALSE) { + return $output; + } + + module_load_include('inc', 'poll', 'poll.pages'); + $function = 'poll_page'; + foreach (module_implements('page_manager_override') as $module) { + $call = $module . '_page_manager_override'; + if (($rc = $call('poll')) && function_exists($rc)) { + $function = $rc; + break; + } + } + + // Otherwise, fall back. + return $function(); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_poll_enable($cache, $status) { + variable_set('page_manager_poll_disabled', $status); + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_poll'] = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/search.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/search.inc new file mode 100644 index 0000000000000000000000000000000000000000..9c7fed6bcdce117eb180d8d10f8abc3d277f146e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/search.inc @@ -0,0 +1,290 @@ +<?php + +/** + * @file + * Handle the 'node view' override task. + * + * This plugin overrides node/%node and reroutes it to the page manager, where + * a list of tasks can be used to service this request based upon criteria + * supplied by access plugins. + */ + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_search_page_manager_tasks() { + if (!module_exists('search')) { + return; + } + + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + 'title' => t('Search'), + + // There are multiple search pages, let's override each of them + // separately. + 'subtasks' => TRUE, + 'subtask callback' => 'page_manager_search_subtask', + 'subtasks callback' => 'page_manager_search_subtasks', + + // Menu hooks so that we can alter the node/%node menu entry to point to us. + 'hook menu alter' => 'page_manager_search_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', + 'get arguments' => 'page_manager_search_get_arguments', + 'get context placeholders' => 'page_manager_search_get_contexts', + + ); +} + +/** + * Callback defined by page_manager_search_page_manager_tasks(). + * + * Alter the search tabs to work with page manager. The search flow is + * quite odd, and tracing through the code takes hours to realize + * that the tab you click on does not normally actually handle + * the search. This tries to account for that. + * + * Note to module authors: This tends to work a lot better with modules + * that override their own search pages if their _alter runs *before* + * this one. + */ +function page_manager_search_menu_alter(&$items, $task) { + // We are creating two sets of tabs. One set is for searching without + // keywords. A second set is for searching *with* keywords. This + // is necessary because search/node/% and search/node need to be + // different due to the way the search menu items function. + + // Go through each search module item. + foreach (module_implements('search') as $name) { + // Do not bother with search menu items that should not have search tabs. + if (!module_invoke($name, 'search', 'name', NULL, TRUE)) { + continue; + } + + // Put these items under the default search tab which is node. + $items["search/$name/%menu_tail"]['tab_parent'] = "search/node/%menu_tail"; + $items["search/$name/%menu_tail"]['tab_root'] = "search/node/%menu_tail"; + + $callback = $items["search/$name/%menu_tail"]['page callback']; + + // Even if a search page is not implemented, we need to add an extra + // entry anyway, for two reasons. + // + // 1) The 'search' menu entry actually handles all entries by default + // and that is going to be bad if the node search is overridden and + // 2) We need to have dual entries to make sure that the tabs are right. + if (variable_get('page_manager_search_disabled_' . $name, TRUE) || ($callback != 'search_view' && !variable_get('page_manager_override_anyway', FALSE))) { + $items["search/$name"] = $items["search/$name/%menu_tail"]; + + // Put these items under the real search tab. + $items["search/$name"]['tab_parent'] = 'search'; + $items["search/$name"]['tab_root'] = 'search'; + + if ($name == 'node') { + $items["search/$name"]['type'] = MENU_DEFAULT_LOCAL_TASK; + // The default tab should always be left weighted. Because of the way + // menu sorts, this item tends to float around if not weighted. + $items["search/$name"]['weight'] = -10; + $items["search/$name/%menu_tail"]['weight'] = -10; + } + + if ($callback == 'search_view' || variable_get('page_manager_override_anyway', FALSE)) { + $items["search/$name/%menu_tail"]['page callback'] = 'page_manager_search_view'; + $items["search/$name/%menu_tail"]['file path'] = $task['path']; + $items["search/$name/%menu_tail"]['file'] = $task['file']; + } + + continue; + } + + if ($callback == 'search_view' || variable_get('page_manager_override_anyway', FALSE)) { + $items["search/$name/%menu_tail"]['page callback'] = 'page_manager_search_page'; + $items["search/$name/%menu_tail"]['file path'] = $task['path']; + $items["search/$name/%menu_tail"]['file'] = $task['file']; + + // Add a version that doesn't contain the menu tail for the no keywords + // version. Ordinarily this works because the top level 'search' just + // passes through. + $items["search/$name"] = $items["search/$name/%menu_tail"]; + $items["search/$name/%menu_tail"]['page arguments'] = array(1, 2); + + // Put these items under the real search tab. + $items["search/$name"]['tab_parent'] = 'search'; + $items["search/$name"]['tab_root'] = 'search'; + + // Content search is the default search link, so we have to override + // the default task as well. + if ($name == 'node') { + $items["search/$name"]['type'] = MENU_DEFAULT_LOCAL_TASK; + // The default tab should always be left weighted. Because of the way + // menu sorts, this item tends to float around if not weighted. + $items["search/$name"]['weight'] = -10; + $items["search/$name/%menu_tail"]['weight'] = -10; + + $items["search"]['page callback'] = 'page_manager_search_page'; + $items["search"]['page arguments'] = array('node'); + $items["search"]['file path'] = $task['path']; + $items["search"]['file'] = $task['file']; + } + } + else { + + // automatically disable this task if it cannot be enabled. + variable_set('page_manager_search_disabled_' . $name, TRUE); + if (!empty($GLOBALS['page_manager_enabling_search'])) { + drupal_set_message(t('Page manager module is unable to enable search/@name/%menu_tail because some other module already has overridden with %callback.', array('%callback' => $callback, '@name' => $name)), 'error'); + } + } + } +} + +/** + * Replacement function for normal search view. + * + * This function resets the active trail because menu system loses track + * of it due to the special way we're handling search items. + */ +function page_manager_search_view($type = 'node') { + ctools_include('menu'); + menu_set_active_trail(ctools_get_menu_trail('search/' . $type)); + + module_load_include('inc', 'search', 'search.pages'); + return search_view($type); +} + +/** + * Entry point for our overridden node view. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * node view, which is node_page_view(). + */ +function page_manager_search_page($type) { + ctools_include('menu'); + menu_set_active_trail(ctools_get_menu_trail('search/' . $type)); + + // Get the arguments and construct a keys string out of them. + $args = func_get_args(); + + // We have to remove the $type. + array_shift($args); + + // And implode() it all back together. + $keys = $args ? implode('/', $args) : ''; + + // Load my task plugin + $task = page_manager_get_task('search'); + $subtask = page_manager_get_task_subtask($task, $type); + + // Load the node into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + $contexts = ctools_context_handler_get_task_contexts($task, $subtask, array($keys)); + + $output = ctools_context_handler_render($task, $subtask, $contexts, array($keys)); + if ($output !== FALSE) { + return $output; + } + + $function = 'search_view'; + foreach (module_implements('page_manager_override') as $module) { + $call = $module . '_page_manager_override'; + if (($rc = $call('search')) && function_exists($rc)) { + $function = $rc; + break; + } + } + + // Otherwise, fall back. + + // Put the $type back on the arguments. + module_load_include('inc', 'search', 'search.pages'); + array_unshift($args, $type); + return call_user_func_array($function, $args); +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the node view and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function page_manager_search_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'keywords', + 'identifier' => t('Keywords'), + 'id' => 1, + 'name' => 'string', + 'settings' => array('use_tail' => TRUE), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function page_manager_search_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(page_manager_search_get_arguments($task, $subtask_id)); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_search_enable($cache, $status) { + variable_set('page_manager_search_disabled_' . $cache->subtask_id, $status); + + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_search'] = TRUE; + } +} + +/** + * Task callback to get all subtasks. + * + * Return a list of all subtasks. + */ +function page_manager_search_subtasks($task) { + foreach (module_implements('search') as $name) { + if(module_invoke($name, 'search', 'name')) { + $return[$name] = page_manager_search_build_subtask($task, $name); + } + } + + return $return; +} + +/** + * Callback to return a single subtask. + */ +function page_manager_search_subtask($task, $subtask_id) { + return page_manager_search_build_subtask($task, $subtask_id); +} + +/** + * Build a subtask array for a given page. + */ +function page_manager_search_build_subtask($task, $name) { + $type = module_invoke($name, 'search', 'name', TRUE); + $subtask = array( + 'name' => $name, + 'admin title' => $type, + 'admin path' => "search/$name/!keywords", + 'admin description' => t('Search @type', array('@type' => $type)), + 'admin type' => t('System'), + 'row class' => empty($page->disabled) ? 'page-manager-enabled' : 'page-manager-disabled', + 'storage' => t('In code'), + 'disabled' => variable_get('page_manager_search_disabled_' . $name, TRUE), + // This works for both enable AND disable + 'enable callback' => 'page_manager_search_enable', + ); + + return $subtask; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/term_view.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/term_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..33863b4259c6ff9add767ba663bc0cd2cf1adedf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/term_view.inc @@ -0,0 +1,288 @@ +<?php + +/** + * @file + * Handle the 'term view' override task. + * + * This plugin overrides term/%term and reroutes it to the page manager, where + * a list of tasks can be used to service this request based upon criteria + * supplied by access plugins. + */ + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_term_view_page_manager_tasks() { + if (module_exists('taxonomy')) { + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + + 'title' => t('Taxonomy term template'), + 'admin title' => t('Taxonomy term template'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for displaying taxonomy terms at <em>taxonomy/term/%term</em>. If you add variants, you may use selection criteria such as vocabulary or user access to provide different displays of the taxonomy term and associated nodes. If no variant is selected, the default Drupal taxonomy term display will be used. This page only affects items actually displayed ad taxonomy/term/%term. Some taxonomy terms, such as forums, have their displays moved elsewhere. Also please note that if you are using pathauto, aliases may make a taxonomy terms appear somewhere else, but as far as Drupal is concerned, they are still at taxonomy/term/%term.'), + 'admin path' => 'taxonomy/term/%term', + 'admin summary' => 'page_manager_term_view_admin_summary', + + // Menu hooks so that we can alter the term/%term menu entry to point to us. + 'hook menu' => 'page_manager_term_view_menu', + 'hook menu alter' => 'page_manager_term_view_menu_alter', + + // Provide a setting to the primary settings UI for Panels + 'admin settings' => 'page_manager_term_view_admin_settings', + // Even though we don't have subtasks, this allows us to save our settings. + 'save subtask callback' => 'page_manager_term_view_save', + + // Callback to add items to the page manager task administration form: + 'task admin' => 'page_manager_term_view_task_admin', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', + 'get arguments' => 'page_manager_term_view_get_arguments', + 'get context placeholders' => 'page_manager_term_view_get_contexts', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_term_view_disabled', TRUE), + 'enable callback' => 'page_manager_term_view_enable', + + // Allow additional operations + 'operations' => array( + 'settings' => array( + 'title' => t('Settings'), + 'description' => t('Edit name, path and other basic settings for the page.'), + 'form' => 'page_manager_term_view_settings', + ), + ), + ); + } +} + +/** + * Callback defined by page_manager_term_view_page_manager_tasks(). + * + * Alter the term view input so that term view comes to us rather than the + * normal term view process. + */ +function page_manager_term_view_menu_alter(&$items, $task) { + if (variable_get('page_manager_term_view_disabled', TRUE)) { + return; + } + + // Override the term view handler for our purpose, but only if someone else + // has not already done so. + if (isset($items['taxonomy/term/%']) && $items['taxonomy/term/%']['page callback'] == 'taxonomy_term_page' || variable_get('page_manager_override_anyway', FALSE)) { + $items['taxonomy/term/%']['page callback'] = 'page_manager_term_view'; + $items['taxonomy/term/%']['file path'] = $task['path']; + $items['taxonomy/term/%']['file'] = $task['file']; + } + else { + // automatically disable this task if it cannot be enabled. + variable_set('page_manager_term_view_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_term_view'])) { + drupal_set_message(t('Page manager module is unable to enable taxonomy/term/%term because some other module already has overridden with %callback.', array('%callback' => $items['taxonomy/term/%']['page callback'])), 'error'); + } + } +} + +/** + * Entry point for our overridden term view. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * term view, which is term_page_view(). + */ +function page_manager_term_view($terms, $depth = 0, $op = 'page') { + // While we ordinarily should never actually get feeds through here, + // just in case + if ($op != 'feed') { + // Load my task plugin + $task = page_manager_get_task('term_view'); + + // Load the term into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($terms, $depth)); + + if (empty($contexts)) { + return drupal_not_found(); + } + + // Add a fake tab for 'View' so that edit tabs can be added. + if (user_access('administer page manager')) { + ctools_include('menu'); + ctools_menu_add_tab(array( + 'title' => t('View'), + 'href' => $_GET['q'], + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + )); + } + + $output = ctools_context_handler_render($task, '', $contexts, array($terms, $depth, $op)); + if ($output !== FALSE) { + return $output; + } + } + + // Otherwise, fall back. + module_load_include('inc', 'taxonomy', 'taxonomy.pages'); + return taxonomy_term_page($terms, $depth, $op); +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the term view and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function page_manager_term_view_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'term', + 'identifier' => variable_get('page_manager_term_view_type', 'multiple') == 'multiple' ? t('Term(s) being viewed') : t('Term being viewed'), + 'id' => 1, + 'name' => variable_get('page_manager_term_view_type', 'multiple') == 'multiple' ? 'terms' : 'term', + 'settings' => array('input_form' => 'tid', 'breadcrumb' => variable_get('page_manager_taxonomy_breadcrumb', TRUE)), + 'default' => '404', + ), + array( + 'keyword' => 'depth', + 'identifier' => t('Depth'), + 'id' => 1, + 'name' => 'string', + 'settings' => array(), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function page_manager_term_view_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(page_manager_term_view_get_arguments($task, $subtask_id)); +} + +/** + * Settings page for this item. + */ +function page_manager_term_view_settings(&$form, &$form_state) { + // This passes thru because the setting can also appear on the main Panels + // settings form. If $settings is an array it will just pick up the default. + $settings = isset($form_state->update_values) ? $form_state->update_values : array(); + page_manager_term_view_admin_settings($form, $settings); +} + +/** + * Copy form values into the page cache. + */ +function page_manager_term_view_settings_submit(&$form, &$form_state) { + $form_state['page']->update_values = $form_state['values']; +} + +/** + * Save when the page cache is saved. + */ +function page_manager_term_view_save($subtask, $cache) { + if (isset($cache->update_values)) { + variable_set('page_manager_term_view_type', $cache->update_values['page_manager_term_view_type']); + variable_set('page_manager_taxonomy_breadcrumb', $cache->update_values['page_manager_taxonomy_breadcrumb']); + } +} + +/** + * Provide a setting to the Panels administrative form. + */ +function page_manager_term_view_admin_settings(&$form, $settings = array()) { + if (empty($settings)) { + $settings = array( + 'page_manager_term_view_type' => variable_get('page_manager_term_view_type', 'multiple'), + 'page_manager_taxonomy_breadcrumb' => variable_get('page_manager_taxonomy_breadcrumb', TRUE), + ); + } + + $form['page_manager_term_view_type'] = array( + '#type' => 'radios', + '#title' => t('Allow multiple terms on taxonomy/term/%term'), + '#options' => array('single' => t('Single term'), 'multiple' => t('Multiple terms')), + '#description' => t('By default, Drupal allows multiple terms as an argument by separating them with commas or plus signs. If you set this to single, that feature will be disabled.'), + '#default_value' => $settings['page_manager_term_view_type'], + ); + $form['page_manager_taxonomy_breadcrumb'] = array( + '#title' => t('Inject hierarchy of first term into breadcrumb trail'), + '#type' => 'checkbox', + '#default_value' => $settings['page_manager_taxonomy_breadcrumb'], + '#description' => t('If checked, taxonomy term parents will appear in the breadcrumb trail.'), + ); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_term_view_enable($cache, $status) { + variable_set('page_manager_term_view_disabled', $status); + + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_term_view'] = TRUE; + } +} + +/** + * Provide a nice administrative summary of the page so an admin can see at a + * glance what this page does and how it is configured. + */ +function page_manager_term_view_admin_summary($task, $subtask) { + $task_name = page_manager_make_task_name($task['name'], $subtask['name']); + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Path')), + array('class' => t('page-summary-data'), 'data' => 'taxonomy/term/%term'), + array('class' => t('page-summary-operation'), 'data' => ''), + ); + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Access')), + array('class' => t('page-summary-data'), 'data' => t('This page is publicly accessible.')), + array('class' => t('page-summary-operation'), 'data' => ''), + ); + + $menu = t('No menu entry'); + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Menu')), + array('class' => t('page-summary-data'), 'data' => $menu), + array('class' => t('page-summary-operation'), 'data' => ''), + ); + + if (variable_get('page_manager_term_view_type', 'multiple') == 'multiple') { + $message = t('Multiple terms may be used, separated by , or +.'); + } + else { + $message = t('Only a single term may be used.'); + } + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('%term')), + array('class' => t('page-summary-data'), 'data' => $message), + array('class' => t('page-summary-operation'), 'data' => ''), + ); + + if (variable_get('page_manager_taxonomy_breadcrumb', TRUE)) { + $message = t('Breadcrumb trail will contain taxonomy term hierarchy'); + } + else { + $message = t('Breadcrumb trail will not contain taxonomy term hiearchy.'); + } + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Breadcrumb')), + array('class' => t('page-summary-data'), 'data' => $message), + array('class' => t('page-summary-operation'), 'data' => ''), + ); + + $output = theme('table', array(), $rows, array('id' => 'page-manager-page-summary')); + return $output; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/user_view.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/user_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..89592524a37b9dafbaf6cc1639300af253347f75 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/plugins/tasks/user_view.inc @@ -0,0 +1,126 @@ +<?php + +/** + * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for + * more information. + */ +function page_manager_user_view_page_manager_tasks() { + return array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + 'title' => t('User profile template'), + 'admin title' => t('User profile template'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for displaying user profiles at <em>user/%user</em>. If you add variants, you may use selection criteria such as roles or user access to provide different views of user profiles. If no variant is selected, the default Drupal user view will be used. Please note that if you are using pathauto, aliases may make a node to be somewhere else, but as far as Drupal is concerned, they are still at user/%user.'), + 'admin path' => 'user/%user', + + // Callback to add items to the page managertask administration form: + 'task admin' => 'page_manager_user_view_task_admin', + + 'hook menu' => 'page_manager_user_view_menu', + 'hook menu alter' => 'page_manager_user_view_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', // handler type -- misnamed + 'get arguments' => 'page_manager_user_view_get_arguments', + 'get context placeholders' => 'page_manager_user_view_get_contexts', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('page_manager_user_view_disabled', TRUE), + 'enable callback' => 'page_manager_user_view_enable', + ); +} + +/** + * Callback defined by page_manager_user_view_page_manager_tasks(). + * + * Alter the user view input so that user view comes to us rather than the + * normal user view process. + */ +function page_manager_user_view_menu_alter(&$items, $task) { + if (variable_get('page_manager_user_view_disabled', TRUE)) { + return; + } + + // Override the user view handler for our purpose. + if ($items['user/%user_uid_optional']['page callback'] == 'user_view' || variable_get('page_manager_override_anyway', FALSE)) { + $items['user/%user_uid_optional']['page callback'] = 'page_manager_user_view'; + $items['user/%user_uid_optional']['file path'] = $task['path']; + $items['user/%user_uid_optional']['file'] = $task['file']; + } + else { + // automatically disable this task if it cannot be enabled. + variable_set('page_manager_user_view_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_user_view'])) { + drupal_set_message(t('Page manager module is unable to enable user/%user because some other module already has overridden with %callback.', array('%callback' => $items['user/%user_uid_optional']['page callback'])), 'error'); + } + } +} + +/** + * Entry point for our overridden user view. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * user view, which is user_page_view(). + */ +function page_manager_user_view($account) { + // Load my task plugin: + $task = page_manager_get_task('user_view'); + + // Load the account into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($account)); + + $output = ctools_context_handler_render($task, '', $contexts, array($account->uid)); + if ($output === FALSE) { + // Fall back! + module_load_include('inc', 'user', 'user.pages'); + $output = user_view($account); + } + else { + //fire off "view" op so that triggers still work + $array = array(); + user_module_invoke('view', $array, $account); + } + return $output; +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the node view and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function page_manager_user_view_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'user', + 'identifier' => t('User being viewed'), + 'id' => 1, + 'name' => 'uid', + 'settings' => array(), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function page_manager_user_view_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(page_manager_user_view_get_arguments($task, $subtask_id)); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function page_manager_user_view_enable($cache, $status) { + variable_set('page_manager_user_view_disabled', $status); + + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_user_view'] = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/theme/page-manager-edit-page.tpl.php b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/theme/page-manager-edit-page.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..316e6b8d1036b19ceaf77d09732931f7cdb69a89 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/theme/page-manager-edit-page.tpl.php @@ -0,0 +1,53 @@ +<?php +/** + * @file + * Template for the page manager page editor. + * + * Variables available: + * - + * + * For javascript purposes the id must not change. + */ +?> +<div id="page-manager-edit"> + <?php print $locked; ?> + <div class="page-manager-wrapper"> + <?php if (isset($operations['primary'])): ?> + <div class="primary-actions clear-block actions"> + <?php print $operations['primary']; ?> + </div> + <?php endif; ?> + <div class="page-manager-tabs clear-block"> + <div class="page-manager-edit-operations"> + <div class="inside"> + <?php print $operations['nav']; ?> + </div> + </div> + <div class="page-manager-ajax-pad"> + <div class="inside"> + <div class="content-header"> + <div class="content-title"> + <?php print $changed; ?> + <?php print $content['title']; ?> + </div> + <?php if (isset($operations['secondary'])): ?> + <div class="secondary-actions clear-block actions"> + <?php print $operations['secondary']; ?> + </div> + <?php endif; ?> + </div> + + <div class="content-content"> + <?php if (!empty($content['description'])): ?> + <div class="description"> + <?php print $content['description']; ?> + </div> + <?php endif; ?> + <?php print $content['content']; ?> + </div> + </div> + </div> + </div> + </div> + <?php print $save; ?> +</div> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/theme/page_manager.theme.inc b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/theme/page_manager.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..85acec98c46bc59785a8be718b9818f531af8d14 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/page_manager/theme/page_manager.theme.inc @@ -0,0 +1,139 @@ +<?php +// $Id + +/** + * @file + * Preprocess functions for page manager editing templates. + */ + +/** + * Preprocess the page manager edit page. + */ +function template_preprocess_page_manager_edit_page(&$vars) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_modal_add_js(); + ctools_add_js('dependent'); + + drupal_add_css(drupal_get_path('module', 'page_manager') . '/css/page-manager.css'); + ctools_add_css('wizard'); + + $task = $vars['page']->task; + $task_handler_plugins = page_manager_get_task_handler_plugins($task); + foreach ($task_handler_plugins as $id => $plugin) { + if (isset($plugin['admin css'])) { + foreach ($plugin['admin css'] as $file) { + drupal_add_css($file); + } + } + if (isset($plugin['admin js'])) { + foreach ($plugin['admin js'] as $file) { + drupal_add_js($file); + } + } + } + + $page = &$vars['page']; + + $vars['locked'] = ''; + $vars['changed'] = ''; + if (!empty($page->locked)) { + $vars['locked'] = theme('page_manager_lock', $page); + $vars['changed'] = theme('page_manager_changed', t('Locked'), t('This page is being edited by another user and you cannot make changes to it.')); + } + else if (!empty($page->new)) { + $vars['changed'] = theme('page_manager_changed', t('New'), t('This page is newly created and has not yet been saved to the database. It will not be available until you save it.')); + } + else if (!empty($page->changed)) { + $vars['changed'] = theme('page_manager_changed', t('Changed'), t('This page has been modified, but these modifications are not yet live. While modifying this page, it is locked from modification by other users.')); + } + + $form_state = array( + 'page' => &$vars['page'], + ); + + $active = $vars['content']['active']; + if ($active[0] == 'handlers' && isset($vars['operations'][$active[1]])) { + $vars['operations']['secondary'] = $vars['operations'][$active[1]]; + } +} + +/** + * Remove some items from the form so they don't submit. + */ +function theme_page_manager_list_pages_form($form) { + // Don't render these: +/* + unset($form['form_id']); + unset($form['form_build_id']); + unset($form['form_token']); +*/ + return '<div class="clear-block">' . drupal_render($form) . '</div>'; +} + +/** + * Turn the rearrange form into a table with tablesorting on. + */ +function theme_page_manager_handler_rearrange($form) { + // Assemble the data for a table from everything in $form['handlers'] + foreach (element_children($form['handlers']) as $id) { + // provide a reference shortcut. + $element = &$form['handlers'][$id]; + if (isset($element['title'])) { + $row = array(); + + $row[] = array( + 'data' => drupal_render($element['title']), + 'class' => 'page-manager-handler', + ); + + $element['weight']['#attributes']['class'] = 'weight'; + $row[] = drupal_render($element['weight']); + + $rows[] = array('data' => $row, 'class' => 'draggable', 'id' => 'page-manager-row-' . $id); + } + } + + if (empty($rows)) { + $rows[] = array(array('data' => t('No task handlers are defined for this task.'), 'colspan' => '5')); + } + + $header = array( + array('data' => t('Variant'), 'class' => 'page-manager-handler'), + t('Weight'), + ); + + drupal_add_tabledrag('page-manager-arrange-handlers', 'order', 'sibling', 'weight'); + + $output = theme('table', $header, $rows, array('id' => 'page-manager-arrange-handlers')); + $output .= drupal_render($form); + return $output; +} + +/** + * Draw the "this task is locked from editing" box. + */ +function theme_page_manager_lock($page) { + $account = user_load($page->locked->uid); + $name = theme('username', $account); + $lock_age = format_interval(time() - $page->locked->updated); + $break = url(page_manager_edit_url($page->task_name, array('actions', 'break-lock'))); + + ctools_add_css('ctools'); + $output = '<div class="ctools-locked">'; + $output .= t('This page is being edited by user !user, and is therefore locked from editing by others. This lock is !age old. Click here to <a href="!break">break this lock</a>.', array('!user' => $name, '!age' => $lock_age, '!break' => $break)); + $output .= '</div>'; + return $output; +} + +/** + * Draw the "you have unsaved changes and this task is locked." message. + */ +function theme_page_manager_changed($text, $description) { + ctools_add_css('ctools'); + $output = '<div class="page-manager-changed" title="' . $description . '">'; + $output .= $text; + $output .= '</div>'; + + return $output; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/compare_users.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/compare_users.inc new file mode 100644 index 0000000000000000000000000000000000000000..a3a192d9031b74eaf97f1482ea8383ac635d92c1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/compare_users.inc @@ -0,0 +1,69 @@ +<?php + +/** + * @file + * Ctools access plugin to provide access/visiblity if two user contexts are equal. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("User: compare"), + 'description' => t('Compare two users (logged-in user and user being viewed, for example)'), + 'callback' => 'ctools_compare_users_access_check', + 'default' => array( + 'equality' => 1, + ), + 'settings form' => 'ctools_compare_users_settings', + 'summary' => 'ctools_compare_users_ctools_access_summary', + 'required context' => array( + new ctools_context_required(t('First User'), 'user'), + new ctools_context_required(t("Second User"), 'user') + ), +); + +/** + * Settings form for the 'by perm' access plugin + */ +function ctools_compare_users_settings(&$form, &$form_state, $conf) { + + $form['settings']['helptext'] = array( + '#type' => 'markup', + '#value' => '<div>'. t('Grant access based on comparison of the two user contexts. For example, to grant access to a user to view their own profile, choose "logged in user" and "user being viewed" and say "grant access if equal". When they\'re the same, access will be granted.') . '</div>', + ); + + $form['settings']['equality'] = array( + '#type' => 'radios', + '#title' => t('Grant access if user contexts are'), + '#options' => array(1 => t('Equal'), 0 => t('Not equal')), + '#default_value' => $conf['equality'], + ); +} + +/** + * Check for access. + */ +function ctools_compare_users_access_check($conf, $context) { + + if (empty($context) || count($context) != 2 || empty($context[0]->data) || empty($context[1]->data)) { + return FALSE; + } + $account1 = $context[0]->data; + $account2 = $context[1]->data; + + // xor returns false if the two bools are the same, and true if they are not. + // i.e, if we asked for equality and they are equal, return true. + // If we asked for inequality and they are equal, return false. + return ($account1->uid == $account2->uid) xor empty($conf['equality']); +} + +/** + * Describe an instance of this plugin. + */ +function ctools_compare_users_ctools_access_summary($conf, $context) { + $comparison = !empty($conf['equality']) ? "is" : 'is not'; + + return t('@id1 @comp @id2', array('@comp' => $comparison, '@id1' => $context[0]->identifier, '@id2' => $context[1]->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/context_exists.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/context_exists.inc new file mode 100644 index 0000000000000000000000000000000000000000..094a109df6061fc16e6c3b51c1b81be260a88927 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/context_exists.inc @@ -0,0 +1,50 @@ +<?php + +/** + * @file + * Plugin to provide access control/visibility based on existence of a specified context + */ + +$plugin = array( + 'title' => t("Context exists"), + 'description' => t('Control access by whether or not a context exists and contains data.'), + 'callback' => 'ctools_context_exists_ctools_access_check', + 'settings form' => 'ctools_context_exists_ctools_access_settings', + 'summary' => 'ctools_context_exists_ctools_access_summary', + 'required context' => new ctools_context_required(t('Context'), 'any'), + 'defaults' => array('exists' => TRUE), +); + +/** + * Settings form + */ +function ctools_context_exists_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['exists'] = array( + '#type' => 'radios', + '#description' => t("Check to see if the context exists (contains data) or does not exist (contains no data). For example, if a context is optional and the path does not contain an argument for that context, it will not exist."), + '#options' => array(TRUE => t('Exists'), FALSE => t("Doesn't exist")), + '#default_value' => $conf['exists'], + ); +} + +/** + * Check for access + */ +function ctools_context_exists_ctools_access_check($conf, $context) { + // xor returns false if the two bools are the same, and true if they are not. + // i.e, if we asked for context_exists and it does, return true. + // If we asked for context does not exist and it does, return false. + return (empty($context->data) xor !empty($conf['exists'])); +} + +/** + * Provide a summary description based upon the specified context + */ +function ctools_context_exists_ctools_access_summary($conf, $context) { + if (!empty($conf['exists'])) { + return t('@identifier exists', array('@identifier' => $context->identifier)); + } + else { + return t('@identifier does not exist', array('@identifier' => $context->identifier)); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/front.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/front.inc new file mode 100644 index 0000000000000000000000000000000000000000..ae3fdb3fd5dfe7e9075975faf86efe5f4d0b4b40 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/front.inc @@ -0,0 +1,45 @@ +<?php + +/** + * @file + * Plugin to provide access control based on drupal_is_front_page. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Front page'), + 'description' => t('Is this the front page.'), + 'callback' => 'ctools_front_ctools_access_check', + 'default' => array('negate' => 0), + 'settings form' => 'ctools_front_ctools_access_settings', + 'summary' => 'ctools_front_ctools_access_summary', +); + +/** + * Settings form for the 'by parent term' access plugin + */ +function ctools_front_ctools_access_settings(&$form, &$form_state, $conf) { + // No additional configuration necessary. +} + +/** + * Check for access. + */ +function ctools_front_ctools_access_check($conf, $context) { + if (drupal_is_front_page()) { + return TRUE; + } + else { + return FALSE; + } +} + +/** + * Provide a summary description based upon the checked terms. + */ +function ctools_front_ctools_access_summary($conf, $context) { + return t('The front page'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node.inc new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_access.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_access.inc new file mode 100644 index 0000000000000000000000000000000000000000..bdd023c89a307f736fc8aabd6659ef62a0253281 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_access.inc @@ -0,0 +1,88 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon node type. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Node: accessible"), + 'description' => t('Control access with built in Drupal node access test.'), + 'callback' => 'ctools_node_access_ctools_access_check', + 'default' => array('type' => 'view'), + 'settings form' => 'ctools_node_access_ctools_access_settings', + 'settings form submit' => 'ctools_node_access_ctools_access_settings_submit', + 'summary' => 'ctools_node_access_ctools_access_summary', + 'required context' => array( + new ctools_context_required(t('User'), 'user'), + new ctools_context_required(t('Node'), 'node'), + ), +); + +/** + * Settings form for the 'by node_access' access plugin + */ +function ctools_node_access_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['type'] = array( + '#title' => t('Operation'), + '#type' => 'radios', + '#options' => array( + 'view' => t('View'), + 'update' => t('Update'), + 'delete' => t('Delete'), + 'create' => t('Create nodes of the same type'), + ), + '#description' => t('Using built in Drupal node access rules, determine if the user can perform the selected operation on the node.'), + '#default_value' => $conf['type'], + ); +} + +/** + * Check for access. + */ +function ctools_node_access_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + list($user_context, $node_context) = $context; + if (empty($node_context) || empty($node_context->data) || empty($node_context->data->type)) { + return FALSE; + } + + if (empty($user_context) || empty($user_context->data)) { + return FALSE; + } + + if ($conf['type'] == 'create') { + return node_access('create', $node_context->data->type, $user_context->data); + } + else { + return node_access($conf['type'], $node_context->data, $user_context->data); + } +} + +/** + * Provide a summary description based upon the checked node_accesss. + */ +function ctools_node_access_ctools_access_summary($conf, $context) { + list($user_context, $node_context) = $context; + $replacement = array('@user' => $user_context->identifier, '@node' => $node_context->identifier); + + switch ($conf['type']) { + case 'view': + return t('@user can view @node.', $replacement); + + case 'update': + return t('@user can edit @node.', $replacement); + + case 'delete': + return t('@user can delete @node.', $replacement); + + case 'create': + return t('@user can create nodes of the same type as @node.', $replacement); + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_language.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..73737e2310dc99538b7a5036d2e5c70e06edf3d6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_language.inc @@ -0,0 +1,113 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon node type. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +if (module_exists('locale')) { + $plugin = array( + 'title' => t("Node: language"), + 'description' => t('Control access by node language.'), + 'callback' => 'ctools_node_language_ctools_access_check', + 'default' => array('language' => array()), + 'settings form' => 'ctools_node_language_ctools_access_settings', + 'settings form submit' => 'ctools_node_language_ctools_access_settings_submit', + 'summary' => 'ctools_node_language_ctools_access_summary', + 'required context' => new ctools_context_required(t('Node'), 'node'), + ); +} + +/** + * Settings form for the 'by node_language' access plugin + */ +function ctools_node_language_ctools_access_settings(&$form, &$form_state, $conf) { + $options = array( + 'current' => t('Current site language'), + 'default' => t('Default site language'), + 'no_language' => t('No language'), + ); + $options = array_merge($options, locale_language_list()); + $form['settings']['language'] = array( + '#title' => t('Language'), + '#type' => 'checkboxes', + '#options' => $options, + '#description' => t('Pass only if the node is in one of the selected languages.'), + '#default_value' => $conf['language'], + ); +} + +/** + * Check for access. + */ +function ctools_node_language_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data) || !isset($context->data->language)) { + return FALSE; + } + + global $language; + + // Specialcase: if 'no language' is checked, return TRUE if the language field is + // empty. + if (!empty($conf['language']['no_language'])) { + if (empty($context->data->language)) { + return TRUE; + } + } + + // Specialcase: if 'current' is checked, return TRUE if the current site language + // matches the node language. + if (!empty($conf['language']['current'])) { + if ($context->data->language == $language->language) { + return TRUE; + } + } + + // Specialcase: If 'default' is checked, return TRUE if the default site language + // matches the node language. + if (!empty($conf['language']['default'])) { + if ($context->data->language == language_default('language')) { + return TRUE; + } + } + + if (array_filter($conf['language']) && empty($conf['language'][$context->data->language])) { + return FALSE; + } + + return TRUE; +} + +/** + * Provide a summary description based upon the checked node_languages. + */ +function ctools_node_language_ctools_access_summary($conf, $context) { + $languages = array( + 'current' => t('Current site language'), + 'default' => t('Default site language'), + 'no_language' => t('No language'), + ); + $languages = array_merge($languages, locale_language_list()); + + if (!isset($conf['language'])) { + $conf['language'] = array(); + } + + $names = array(); + foreach (array_filter($conf['language']) as $language) { + $names[] = $languages[$language]; + } + + if (empty($names)) { + return t('@identifier is in any language', array('@identifier' => $context->identifier)); + } + + return format_plural(count($names), '@identifier language is "@languages"', '@identifier language is one of "@languages"', array('@languages' => implode(', ', $names), '@identifier' => $context->identifier)); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_type.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..de0d786916e04cda506baa609fc7fea38a0eafdc --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/node_type.inc @@ -0,0 +1,99 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon node type. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Node: type"), + 'description' => t('Control access by node_type.'), + 'callback' => 'ctools_node_type_ctools_access_check', + 'default' => array('type' => array()), + 'settings form' => 'ctools_node_type_ctools_access_settings', + 'settings form submit' => 'ctools_node_type_ctools_access_settings_submit', + 'summary' => 'ctools_node_type_ctools_access_summary', + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'restrictions' => 'ctools_node_type_ctools_access_restrictions', +); + +/** + * Settings form for the 'by node_type' access plugin + */ +function ctools_node_type_ctools_access_settings(&$form, &$form_state, $conf) { + $types = node_get_types(); + foreach ($types as $type => $info) { + $options[$type] = check_plain($info->name); + } + + $form['settings']['type'] = array( + '#title' => t('Node type'), + '#type' => 'checkboxes', + '#options' => $options, + '#description' => t('Only the checked node types will be valid.'), + '#default_value' => $conf['type'], + ); +} + +/** + * Compress the node_types allowed to the minimum. + */ +function ctools_node_type_ctools_access_settings_submit(&$form, &$form_state) { + $form_state['values']['settings']['type'] = array_filter($form_state['values']['settings']['type']); +} + +/** + * Check for access. + */ +function ctools_node_type_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data) || empty($context->data->type)) { + return FALSE; + } + + if (array_filter($conf['type']) && empty($conf['type'][$context->data->type])) { + return FALSE; + } + + return TRUE; +} + +/** + * Inform the UI that we've eliminated a bunch of possibilities for this + * context. + */ +function ctools_node_type_ctools_access_restrictions($conf, &$context) { + if (isset($context->restrictions['type'])) { + $context->restrictions['type'] = array_unique(array_merge($context->restrictions['type'], array_keys(array_filter($conf['type'])))); + } + else { + $context->restrictions['type'] = array_keys(array_filter($conf['type'])); + } +} + +/** + * Provide a summary description based upon the checked node_types. + */ +function ctools_node_type_ctools_access_summary($conf, $context) { + if (!isset($conf['type'])) { + $conf['type'] = array(); + } + $types = node_get_types(); + + $names = array(); + foreach (array_filter($conf['type']) as $type) { + $names[] = check_plain($types[$type]->name); + } + + if (empty($names)) { + return t('@identifier is any node type', array('@identifier' => $context->identifier)); + } + + return format_plural(count($names), '@identifier is type "@types"', '@identifier type is one of "@types"', array('@types' => implode(', ', $names), '@identifier' => $context->identifier)); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/path_visibility.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/path_visibility.inc new file mode 100644 index 0000000000000000000000000000000000000000..ea652c8623ec9490c52c4bc2be1c0f191bd9346f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/path_visibility.inc @@ -0,0 +1,87 @@ +<?php + +/** + * @file + * Plugin to provide access control/visibility based on path. + */ + +$plugin = array( + 'title' => t('String: URL path'), + 'description' => t('Control access by the current path.'), + 'callback' => 'ctools_path_visibility_ctools_access_check', + 'settings form' => 'ctools_path_visibility_ctools_access_settings', + 'summary' => 'ctools_path_visibility_ctools_access_summary', + 'required context' => new ctools_context_optional(t('Path'), 'string'), + 'default' => array('visibility_setting' => 1, 'paths' => ''), +); + +/** + * Settings form + */ +function ctools_path_visibility_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['note'] = array( + '#value' => '<div class="description">' . t('Note: if no context is chosen, the current page path will be used.') . '</div>', + ); + + $form['settings']['visibility_setting'] = array( + '#type' => 'radios', + '#options' => array( + 1 => t('Allow access on the following pages'), + 0 => t('Allow access on all pages except the following pages'), + ), + '#default_value' => $conf['visibility_setting'], + ); + + $form['settings']['paths'] = array( + '#type' => 'textarea', + '#title' => t('Paths'), + '#default_value' => $conf['paths'], + '#description' => t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>')), + ); +} + +/** + * Check for access. + */ +function ctools_path_visibility_ctools_access_check($conf, $context) { + if (isset($context->data)) { + $base_path = $context->data; + } + else { + $base_path = $_GET['q']; + } + + $path = drupal_get_path_alias($base_path); + $page_match = drupal_match_path($path, $conf['paths']); + + // If there's a path alias, we may still be at the un-aliased path + // so check that as well. + if (!isset($context->data) && $path != $base_path) { + $page_match = $page_match || drupal_match_path($base_path, $conf['paths']); + } + + // When $conf['visibility_setting'] has a value of 0, the block is displayed + // on all pages except those listed in $block->pages. When set to 1, it + // is displayed only on those pages listed in $block->pages. + $page_match = !($conf['visibility_setting'] xor $page_match); + + return $page_match; +} + +/** + * Provide a summary description. + */ +function ctools_path_visibility_ctools_access_summary($conf, $context) { + $paths = array(); + foreach (explode("\n", $conf['paths']) as $path) { + $paths[] = check_plain($path); + } + + $identifier = $context->type == 'any' ? t('Current path') : $context->identifier; + if ($conf['visibility_setting']) { + return format_plural(count($paths), '@identifier is "@paths"', '@identifier type is one of "@paths"', array('@paths' => implode(', ', $paths), '@identifier' => $identifier)); + } + else { + return format_plural(count($paths), '@identifier is not "@paths"', '@identifier type is not one of "@paths"', array('@paths' => implode(', ', $paths), '@identifier' => $identifier)); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/perm.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/perm.inc new file mode 100644 index 0000000000000000000000000000000000000000..d2023f3dbdb1985defe25c163d6d8b0f00d27504 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/perm.inc @@ -0,0 +1,68 @@ +<?php + +/** + * @file + * Plugin to provide access control based on user permission strings. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("User: permission"), + 'description' => t('Control access by permission string.'), + 'callback' => 'ctools_perm_ctools_access_check', + 'default' => array('perm' => 'access content'), + 'settings form' => 'ctools_perm_ctools_access_settings', + 'summary' => 'ctools_perm_ctools_access_summary', + 'required context' => new ctools_context_required(t('User'), 'user'), +); + +/** + * Settings form for the 'by perm' access plugin + */ +function ctools_perm_ctools_access_settings(&$form, &$form_state, $conf) { + $perms = array(); + // Get list of permissions + foreach (module_list(FALSE, FALSE, TRUE) as $module) { + // By keeping them keyed by module we can use optgroups with the + // 'select' type. + if ($permissions = module_invoke($module, 'perm')) { + $perms[$module] = drupal_map_assoc($permissions); + } + } + + $form['settings']['perm'] = array( + '#type' => 'select', + '#options' => $perms, + '#title' => t('Permission'), + '#default_value' => $conf['perm'], + '#description' => t('Only users with the selected permission flag will be able to access this.'), + ); +} + +/** + * Check for access. + */ +function ctools_perm_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data)) { + return FALSE; + } + + return user_access($conf['perm'], $context->data); +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_perm_ctools_access_summary($conf, $context) { + if (!isset($conf['perm'])) { + return t('Error, unset permission'); + } + + return t('@identifier has "@perm"', array('@identifier' => $context->identifier, '@perm' => $conf['perm'])); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/php.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/php.inc new file mode 100644 index 0000000000000000000000000000000000000000..80e7dd9dcf5b775df3adff3e13760fc66053c77a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/php.inc @@ -0,0 +1,63 @@ +<?php + +/** + * @file + * Plugin to provide access control based on evaluated PHP. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("PHP Code"), + 'description' => t('Control access through arbitrary PHP code.'), + 'callback' => 'ctools_php_ctools_access_check', + 'default' => array('description' => '', 'php' => ''), + 'settings form' => 'ctools_php_ctools_access_settings', + 'summary' => 'ctools_php_ctools_access_summary', + 'all contexts' => TRUE, +); + +/** + * Settings form for the 'by perm' access plugin + * + * @todo Need a way to provide a list of all available contexts to be used by + * the eval-ed PHP. + */ +function ctools_php_ctools_access_settings(&$form, &$form_state, $conf) { + $perms = array(); + + $form['settings']['description'] = array( + '#type' => 'textfield', + '#title' => t('Administrative desc'), + '#default_value' => $conf['description'], + '#description' => t('A description for this test for administrative purposes.'), + ); + $form['settings']['php'] = array( + '#type' => 'textarea', + '#title' => t('PHP Code'), + '#default_value' => $conf['php'], + '#description' => t('Access will be granted if the following PHP code returns <code>TRUE</code>. Do not include <?php ?>. Note that executing incorrect PHP-code can break your Drupal site. All contexts will be available in the <em>$contexts</em> variable.'), + ); + if (!user_access('use PHP for block visibility')) { + $form['settings']['php']['#disabled'] = TRUE; + $form['settings']['php']['#value'] = $conf['php']; + $form['settings']['php']['#description'] .= ' ' . t('You do not have sufficient permissions to edit PHP code.'); + } +} + +/** + * Check for access. + */ +function ctools_php_ctools_access_check($__conf, $contexts) { + $access = eval($__conf['php']); + return $access; +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_php_ctools_access_summary($conf, $contexts) { + return !empty($conf['description']) ? check_plain($conf['description']) : t('No description'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/role.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/role.inc new file mode 100644 index 0000000000000000000000000000000000000000..fc61dc851ef08d1c161be652a3beac0a49ab6c3b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/role.inc @@ -0,0 +1,78 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon role membership. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("User: role"), + 'description' => t('Control access by role.'), + 'callback' => 'ctools_role_ctools_access_check', + 'default' => array('rids' => array()), + 'settings form' => 'ctools_role_ctools_access_settings', + 'settings form submit' => 'ctools_role_ctools_access_settings_submit', + 'summary' => 'ctools_role_ctools_access_summary', + 'required context' => new ctools_context_required(t('User'), 'user'), +); + +/** + * Settings form for the 'by role' access plugin + */ +function ctools_role_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['rids'] = array( + '#type' => 'checkboxes', + '#title' => t('Role'), + '#default_value' => $conf['rids'], + '#options' => ctools_get_roles(), + '#description' => t('Only the checked roles will be granted access.'), + ); +} + +/** + * Compress the roles allowed to the minimum. + */ +function ctools_role_ctools_access_settings_submit(&$form, &$form_state) { + $form_state['values']['settings']['rids'] = array_keys(array_filter($form_state['values']['settings']['rids'])); +} + +/** + * Check for access. + */ +function ctools_role_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data) || !isset($context->data->roles)) { + return FALSE; + } + + $roles = array_keys($context->data->roles); + $roles[] = $context->data->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID; + return (bool) array_intersect($conf['rids'], $roles); +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_role_ctools_access_summary($conf, $context) { + if (!isset($conf['rids'])) { + $conf['rids'] = array(); + } + $roles = ctools_get_roles(); + + $names = array(); + foreach (array_filter($conf['rids']) as $rid) { + $names[] = check_plain($roles[$rid]); + } + + if (empty($names)) { + return t('@identifier can have any role', array('@identifier' => $context->identifier)); + } + + return format_plural(count($names), '@identifier has role "@roles"', '@identifier has one of "@roles"', array('@roles' => implode(', ', $names), '@identifier' => $context->identifier)); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/site_language.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/site_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..20ac9590111be5d8b3433dc660c736afc8833fde --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/site_language.inc @@ -0,0 +1,86 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon node type. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +if (module_exists('locale')) { + $plugin = array( + 'title' => t("User: language"), + 'description' => t('Control access by the language the user or site currently uses.'), + 'callback' => 'ctools_site_language_ctools_access_check', + 'default' => array('language' => array()), + 'settings form' => 'ctools_site_language_ctools_access_settings', + 'settings form submit' => 'ctools_site_language_ctools_access_settings_submit', + 'summary' => 'ctools_site_language_ctools_access_summary', + ); +} + +/** + * Settings form for the 'by site_language' access plugin + */ +function ctools_site_language_ctools_access_settings(&$form, &$form_state, $conf) { + $options = array( + 'default' => t('Default site language'), + ); + $options = array_merge($options, locale_language_list()); + $form['settings']['language'] = array( + '#title' => t('Language'), + '#type' => 'checkboxes', + '#options' => $options, + '#description' => t('Pass only if the current site language is one of the selected languages.'), + '#default_value' => $conf['language'], + ); +} + +/** + * Check for access. + */ +function ctools_site_language_ctools_access_check($conf, $context) { + global $language; + + // Specialcase: If 'default' is checked, return TRUE if the default site language + // matches the node language. + if (!empty($conf['language']['default'])) { + if ($language->language == language_default('language')) { + return TRUE; + } + } + + if (array_filter($conf['language']) && empty($conf['language'][$language->language])) { + return FALSE; + } + + return TRUE; +} + +/** + * Provide a summary description based upon the checked site_languages. + */ +function ctools_site_language_ctools_access_summary($conf, $context) { + $languages = array( + 'default' => t('Default site language'), + ); + $languages = array_merge($languages, locale_language_list()); + + if (!isset($conf['language'])) { + $conf['language'] = array(); + } + + $names = array(); + foreach (array_filter($conf['language']) as $language) { + $names[] = $languages[$language]; + } + + if (empty($names)) { + return t('Site language is any language'); + } + + return format_plural(count($names), 'Site language is "@languages"', 'Site language is one of "@languages"', array('@languages' => implode(', ', $names))); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/string_equal.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/string_equal.inc new file mode 100644 index 0000000000000000000000000000000000000000..a90c7c92bb89f288d82f2da3f2f1acf165c92bee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/string_equal.inc @@ -0,0 +1,93 @@ +<?php + +/** + * @file + * Plugin to provide access control/visibility based on specified context string matching user-specified string + */ + +$plugin = array( + 'title' => t("String: comparison"), + 'description' => t('Control access by string match.'), + 'callback' => 'ctools_string_equal_ctools_access_check', + 'settings form' => 'ctools_string_equal_ctools_access_settings', + 'summary' => 'ctools_string_equal_ctools_access_summary', + 'required context' => new ctools_context_required(t('String'), 'string'), + 'defaults' => array('operator' => '=', 'value' => '', 'case' => FALSE), +); + +/** + * Settings form + */ +function ctools_string_equal_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['operator'] = array( + '#type' => 'radios', + '#title' => t('Operator'), + '#options' => array( + '=' => t('Equal'), + '!=' => t('Not equal'), + 'regex' => t('Regular expression'), + '!regex' => t('Not equal to regular expression'), + ), + '#default_value' => $conf['operator'], + '#description' => t('If using a regular expression, you should enclose the pattern in slashes like so: <em>/foo/</em>. If you need to compare against slashes you can use another character to enclose the pattern, such as @. See <a href="http://www.php.net/manual/en/reference.pcre.pattern.syntax.php">PHP regex documentation</a> for more.'), + ); + + $form['settings']['value'] = array( + '#type' => 'textfield', + '#title' => t('String'), + '#default_value' => $conf['value'], + ); + + $form['settings']['case'] = array( + '#type' => 'checkbox', + '#title' => t('Case sensitive'), + '#default_value' => $conf['case'], + ); +} + +/** + * Check for access + */ +function ctools_string_equal_ctools_access_check($conf, $context) { + if (empty($context) || empty($context->data)) { + $string = ''; + } + else { + $string = $context->data; + } + + $value = $conf['value']; + if (empty($conf['case'])) { + $string = drupal_strtolower($string); + $value = drupal_strtolower($value); + } + + switch ($conf['operator']) { + case '=': + return $string === $value; + case '!=': + return $string !== $value; + case 'regex': + return preg_match($value, $string); + case '!regex': + return !preg_match($value, $string); + } +} + +/** + * Provide a summary description based upon the specified context + */ +function ctools_string_equal_ctools_access_summary($conf, $context) { + $values = array('@identifier' => $context->identifier, '@value' => $conf['value']); + switch ($conf['operator']) { + case '=': + return t('@identifier is "@value"', $values); + case '!=': + return t('@identifier is not "@value"', $values); + case 'regex': + return t('@identifier matches "@value"', $values); + case '!regex': + return t('@identifier does not match "@value"', $values); + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/string_length.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/string_length.inc new file mode 100644 index 0000000000000000000000000000000000000000..bca93f0c4f46d20302d043d7f93b373dfa82aa11 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/string_length.inc @@ -0,0 +1,77 @@ +<?php + +/** + * @file + * Plugin to provide access control/visibility based on length of + * a string context. + */ + +$plugin = array( + 'title' => t("String: length"), + 'description' => t('Control access by length of string context.'), + 'callback' => 'ctools_string_length_ctools_access_check', + 'settings form' => 'ctools_string_length_ctools_access_settings', + 'summary' => 'ctools_string_length_ctools_access_summary', + 'required context' => new ctools_context_required(t('String'), 'string'), + 'defaults' => array('operator' => '=', 'length' => 0), +); + +/** + * Settings form for the 'by role' access plugin. + */ +function ctools_string_length_ctools_access_settings(&$form, &$form_state, $conf) { + $form['settings']['operator'] = array( + '#type' => 'radios', + '#title' => t('Operator'), + '#options' => array( + '>' => t('Greater than'), + '>=' => t('Greater than or equal to'), + '=' => t('Equal to'), + '!=' => t('Not equal to'), + '<' => t('Less than'), + '<=' => t('Less than or equal to'), + ), + '#default_value' => $conf['operator'], + ); + $form['settings']['length'] = array( + '#type' => 'textfield', + '#title' => t('Length of string'), + '#size' => 3, + '#default_value' => $conf['length'], + '#description' => t('Access/visibility will be granted based on string context length.'), + ); +} + +/** + * Check for access. + */ +function ctools_string_length_ctools_access_check($conf, $context) { + if (empty($context) || empty($context->data)) { + $length = 0; + } + else { + $length = drupal_strlen($context->data); + } + + switch($conf['operator']) { + case '<': + return $length < $conf['length']; + case '<=': + return $length <= $conf['length']; + case '==': + return $length == $conf['length']; + case '!=': + return $length != $conf['length']; + case '>': + return $length > $conf['length']; + case '>=': + return $length >= $conf['length']; + } +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_string_length_ctools_access_summary($conf, $context) { + return t('@identifier must be @comp @length characters', array('@identifier' => $context->identifier, '@comp' => $conf['operator'], '@length' => $conf['length'])); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term.inc new file mode 100644 index 0000000000000000000000000000000000000000..ee3b410a2c1e7e1eddfad36398bc3a50d9a9a286 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term.inc @@ -0,0 +1,151 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon specific terms. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Taxonomy: term"), + 'description' => t('Control access by a specific term.'), + 'callback' => 'ctools_term_ctools_access_check', + 'default' => array('vids' => array()), + 'settings form' => 'ctools_term_ctools_access_settings', + 'settings form validation' => 'ctools_term_ctools_access_settings_validate', + 'settings form submit' => 'ctools_term_ctools_access_settings_submit', + 'summary' => 'ctools_term_ctools_access_summary', + 'required context' => new ctools_context_required(t('Term'), array('term', 'terms')), +); + +/** + * Settings form for the 'by term' access plugin + */ +function ctools_term_ctools_access_settings(&$form, &$form_state, $conf) { + // If no configuration was saved before, set some defaults. + if (empty($conf)) { + $conf = array( + 'vid' => 0, + ); + } + if (!isset($conf['vid'])) { + $conf['vid'] = 0; + } + + $form['settings']['vid'] = array( + '#title' => t('Vocabulary'), + '#type' => 'select', + '#options' => array(), + '#description' => t('Select the vocabulary for this form.'), + '#id' => 'ctools-select-vid', + '#default_value' => $conf['vid'], + '#required' => TRUE, + ); + + ctools_include('dependent'); + $options = array(); + + // A note: Dependency works strangely on these forms as they have never been + // updated to a more modern system so they are not individual forms of their + // own like the content types. + + $form['settings']['#tree'] = TRUE; + + // Loop over each of the configured vocabularies. + foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) { + $options[$vid] = $vocabulary->name; + $form['settings'][$vocabulary->vid] = array( + '#title' => t('Terms'), + '#description' => t('Select a term or terms from @vocabulary.', array('@vocabulary' => $vocabulary->name)), //. $description, + '#process' => array('ctools_dependent_process'), + '#dependency' => array('ctools-select-vid' => array($vocabulary->vid)), + '#default_value' => !empty($conf[$vid]) ? $conf[$vid] : '', + '#multiple' => TRUE, + ); + + // If it's a tag, use an autocomplete. + if ($vocabulary->tags) { + $form['settings'][$vocabulary->vid]['#type'] = 'textfield'; + $form['settings'][$vocabulary->vid]['#autocomplete_path'] = 'taxonomy/autocomplete/' . $vocabulary->vid; + } + + // Other vocabs just show a list. + else { + $terms = array(); + foreach (taxonomy_get_tree($vid) as $x => $term) { + $terms[$term->tid] = str_repeat('-', $term->depth) . ($term->depth ? ' ' : '') . $term->name; + } + $form['settings'][$vocabulary->vid]['#type'] = 'select'; + $form['settings'][$vocabulary->vid]['#options'] = $terms; + unset($terms); + } + } + $form['settings']['vid']['#options'] = $options; +} + +/** + * Check for access. + */ +function ctools_term_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data) || empty($context->data->vid) || empty($context->data->tid)) { + return FALSE; + } + + // Get the $vid. + if (!isset($conf['vid'])) { + return FALSE; + } + $vid = $conf['vid']; + + // Get the terms. + if (!isset($conf[$vid])) { + return FALSE; + } + + $return = FALSE; + // Tags get saved as an imploded array of strings. + if (!is_array($conf[$vid])) { + $terms = explode(', ', $conf[$vid]); + // For multi-term with names, we'll only accept the first term because + // that is the name we have. + return in_array($context->data->name, $terms); + } + else { + $terms = array_filter($conf[$vid]); + // For multi-term if any terms coincide, let's call that good enough: + if (isset($context->tids)) { + return (bool) array_intersect($terms, $context->tids); + } + else { + return in_array($context->data->tid, $terms); + } + } +} + +/** + * Provide a summary description based upon the checked terms. + */ +function ctools_term_ctools_access_summary($conf, $context) { + $vocab = taxonomy_vocabulary_load($conf['vid']); + if ($vocab->tags) { + $terms = explode(', ', $conf[$vocab->vid]); + } + else { + $terms = array(); + foreach ($conf[$vocab->vid] as $tid) { + $term = taxonomy_get_term($tid); + $terms[] = $term->name; + } + } + + return format_plural(count($terms), + '@term can be the term "@terms"', + '@term can be one of these terms: @terms', + array('@terms' => implode(', ', $terms), + '@term' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term_parent.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term_parent.inc new file mode 100644 index 0000000000000000000000000000000000000000..8587695491c4e7f9bd2db035f2a50fd4c3c6790b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term_parent.inc @@ -0,0 +1,85 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon a parent term. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Taxonomy: parent term"), + 'description' => t('Control access by existence of a parent term.'), + 'callback' => 'ctools_term_parent_ctools_access_check', + 'default' => array('vid' => array(), 'negate' => 0), + 'settings form' => 'ctools_term_parent_ctools_access_settings', + 'settings form validation' => 'ctools_term_parent_ctools_access_settings_validate', + 'settings form submit' => 'ctools_term_parent_ctools_access_settings_submit', + 'summary' => 'ctools_term_parent_ctools_access_summary', + 'required context' => new ctools_context_required(t('Term'), array('term', 'terms')), +); + +/** + * Settings form for the 'by parent term' access plugin + */ +function ctools_term_parent_ctools_access_settings(&$form, &$form_state, $conf) { + // If no configuration was saved before, set some defaults. + if (empty($conf)) { + $conf = array( + 'vid' => 0, + ); + } + if (!isset($conf['vid'])) { + $conf['vid'] = 0; + } + + $form['settings']['vid'] = array( + '#title' => t('Vocabulary'), + '#type' => 'select', + '#options' => array(), + '#description' => t('Select the vocabulary for this form. If there exists a parent term in that vocabulary, this access check will succeed.'), + '#id' => 'ctools-select-vid', + '#default_value' => $conf['vid'], + '#required' => TRUE, + ); + + $options = array(); + + // Loop over each of the configured vocabularies. + foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) { + $options[$vid] = $vocabulary->name; + } + $form['settings']['vid']['#options'] = $options; +} + +/** + * Check for access. + */ +function ctools_term_parent_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data) || empty($context->data->vid) || empty($context->data->tid)) { + return FALSE; + } + + // Get the $vid. + if (!isset($conf['vid'])) { + return FALSE; + } + $vid = $conf['vid']; + + $count = db_result(db_query('SELECT COUNT(*) FROM {term_hierarchy} th INNER JOIN {term_data} td ON th.parent = td.tid WHERE th.tid = %d AND td.vid = %d', $context->data->tid, $vid)); + + return $count ? TRUE : FALSE; +} + +/** + * Provide a summary description based upon the checked terms. + */ +function ctools_term_parent_ctools_access_summary($conf, $context) { + $vocab = taxonomy_vocabulary_load($conf['vid']); + + return t('"@term" has parent in vocabulary "@vocab"', array('@term' => $context->identifier, '@vocab' => $vocab->name)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term_vocabulary.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term_vocabulary.inc new file mode 100644 index 0000000000000000000000000000000000000000..bcf0908000caed2008fc2f7a4b626a32ffb49630 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/term_vocabulary.inc @@ -0,0 +1,86 @@ +<?php + +/** + * @file + * Plugin to provide access control based upon term vocabulary + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Taxonomy: vocabulary"), + 'description' => t('Control access by vocabulary.'), + 'callback' => 'ctools_term_vocabulary_ctools_access_check', + 'default' => array('vids' => array()), + 'settings form' => 'ctools_term_vocabulary_ctools_access_settings', + 'settings form submit' => 'ctools_term_vocabulary_ctools_access_settings_submit', + 'summary' => 'ctools_term_vocabulary_ctools_access_summary', + 'required context' => new ctools_context_required(t('Vocabulary'), array('term', 'terms', 'vocabulary')), +); + +/** + * Settings form for the 'by term_vocabulary' access plugin + */ +function ctools_term_vocabulary_ctools_access_settings(&$form, &$form_state, $conf) { + $options = array(); + $vocabularies = taxonomy_get_vocabularies(); + foreach ($vocabularies as $voc) { + $options[$voc->vid] = check_plain($voc->name); + } + + $form['settings']['vids'] = array( + '#type' => 'checkboxes', + '#title' => t('Vocabularies'), + '#options' => $options, + '#description' => t('Only the checked vocabularies will be valid.'), + '#default_value' => $conf['vids'], + ); +} + +/** + * Compress the term_vocabularys allowed to the minimum. + */ +function ctools_term_vocabulary_ctools_access_settings_submit(&$form, &$form_state) { + $form_state['values']['settings']['vids'] = array_filter($form_state['values']['settings']['vids']); +} + +/** + * Check for access. + */ +function ctools_term_vocabulary_ctools_access_check($conf, $context) { + // As far as I know there should always be a context at this point, but this + // is safe. + if (empty($context) || empty($context->data) || empty($context->data->vid)) { + return FALSE; + } + + if (array_filter($conf['vids']) && empty($conf['vids'][$context->data->vid])) { + return FALSE; + } + + return TRUE; +} + +/** + * Provide a summary description based upon the checked term_vocabularys. + */ +function ctools_term_vocabulary_ctools_access_summary($conf, $context) { + if (!isset($conf['type'])) { + $conf['type'] = array(); + } + $vocabularies = taxonomy_get_vocabularies(); + + $names = array(); + foreach (array_filter($conf['vids']) as $vid) { + $names[] = check_plain($vocabularies[$vid]->name); + } + + if (empty($names)) { + return t('@identifier is any vocabulary', array('@identifier' => $context->identifier)); + } + + return format_plural(count($names), '@identifier vocabulary is "@vids"', '@identifier vocabulary is one of "@vids"', array('@vids' => implode(', ', $names), '@identifier' => $context->identifier)); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/theme.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..d83824eddba25e19ce5d39a75c3371bb8cfa5380 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/access/theme.inc @@ -0,0 +1,69 @@ +<?php + +/** + * @file + * Plugin to provide access control based on user themeission strings. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Current theme"), + 'description' => t('Control access by checking which theme is in use.'), + 'callback' => 'ctools_theme_ctools_access_check', + 'default' => array('theme' => variable_get('theme_default', 'garland')), + 'settings form' => 'ctools_theme_ctools_access_settings', + 'summary' => 'ctools_theme_ctools_access_summary', +); + +/** + * Settings form for the 'by theme' access plugin + */ +function ctools_theme_ctools_access_settings(&$form, &$form_state, $conf) { + $themes = array(); + foreach (list_themes() as $key => $theme) { + $themes[$key] = $theme->info['name']; + } + + $form['settings']['theme'] = array( + '#type' => 'select', + '#options' => $themes, + '#title' => t('Themes'), + '#default_value' => $conf['theme'], + '#description' => t('This will only be accessed if the current theme is the selected theme.'), + ); +} + +/** + * Check for access. + */ +function ctools_theme_ctools_access_check($conf, $context) { + if (!empty($GLOBALS['theme'])) { + $theme = $GLOBALS['theme']; + } + else if (!empty($GLOBALS['custom_theme'])) { + $theme = $GLOBALS['custom_theme']; + } + else if (!empty($GLOBALS['user']->theme)) { + $theme = $GLOBALS['user']->theme; + } + else { + $theme = variable_get('theme_default', 'garland'); + } + + return $conf['theme'] == $theme; +} + +/** + * Provide a summary description based upon the checked roles. + */ +function ctools_theme_ctools_access_summary($conf, $context) { + if (!isset($conf['theme'])) { + return t('Error, unset theme'); + } + $themes = list_themes(); + + return t('Current theme is "@theme"', array('@theme' => $themes[$conf['theme']]->info['name'])); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/nid.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/nid.inc new file mode 100644 index 0000000000000000000000000000000000000000..98342605c123870ca5f956ce11bc46cd4cccbc88 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/nid.inc @@ -0,0 +1,49 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a node id + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Node: ID"), + 'keyword' => 'node', + 'description' => t('Creates a node context from a node ID argument.'), + 'context' => 'ctools_argument_nid_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this argument'), + ), +); + +/** + * Discover if this argument gives us the node we crave. + */ +function ctools_argument_nid_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('node'); + } + + // We can accept either a node object or a pure nid. + if (is_object($arg)) { + return ctools_context_create('node', $arg); + } + + if (!is_numeric($arg)) { + return FALSE; + } + + $node = node_load($arg); + if (!$node) { + return FALSE; + } + + return ctools_context_create('node', $node); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/node_add.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/node_add.inc new file mode 100644 index 0000000000000000000000000000000000000000..c811311b0207a76887dc319f4571e7b0edb41c70 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/node_add.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a Node add form + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Node add form: node type"), + // keyword to use for %substitution + 'keyword' => 'node_type', + 'description' => t('Creates a node add form context from a node type argument.'), + 'context' => 'ctools_node_add_context', +); + +/** + * Discover if this argument gives us the node we crave. + */ +function ctools_node_add_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if (!isset($arg)) { + return ctools_context_create_empty('node_add_form'); + } + + return ctools_context_create('node_add_form', $arg); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/node_edit.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/node_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..c7cdf29e83e8ff1fc3b289ee3331292dae32b2a7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/node_edit.inc @@ -0,0 +1,51 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a Node edit form + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Node edit form: node ID"), + // keyword to use for %substitution + 'keyword' => 'node', + 'description' => t('Creates a node edit form context from a node ID argument.'), + 'context' => 'ctools_node_edit_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this argument'), + ), +); + +/** + * Discover if this argument gives us the node we crave. + */ +function ctools_node_edit_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('node_edit_form'); + } + + // We can accept either a node object or a pure nid. + if (is_object($arg)) { + return ctools_context_create('node_edit_form', $arg); + } + + if (!is_numeric($arg)) { + return FALSE; + } + + $node = node_load($arg); + if (!$node) { + return NULL; + } + + // This will perform a node_access check, so we don't have to. + return ctools_context_create('node_edit_form', $node); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/rid.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/rid.inc new file mode 100644 index 0000000000000000000000000000000000000000..00e34d49a2568ec9c5011a0a21039f7a890cad4f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/rid.inc @@ -0,0 +1,50 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a node revision id + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Revision: ID"), + 'keyword' => 'revision', + 'description' => t('Creates a node context from a revision ID argument.'), + 'context' => 'ctools_argument_rid_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the revision ID of a node for this argument'), + ), +); + +/** + * Discover if this argument gives us the node we crave. + */ +function ctools_argument_rid_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('node'); + } + + // We can accept either a node object or a pure nid. + if (is_object($arg)) { + return ctools_context_create('node', $arg); + } + + if (!is_numeric($arg)) { + return FALSE; + } + + $nid = db_result(db_query("SELECT nid FROM {node_revisions} WHERE vid = %d", $arg)); + $node = node_load($nid, $arg); + if (!$node) { + return FALSE; + } + + return ctools_context_create('node', $node); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/string.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/string.inc new file mode 100644 index 0000000000000000000000000000000000000000..73e9edaa9e24754231c2aea2f299f410dc9a946f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/string.inc @@ -0,0 +1,63 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a raw string + */ +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("String"), + // keyword to use for %substitution + 'keyword' => 'string', + 'description' => t('A string is a minimal context that simply holds a string that can be used for some other purpose.'), + 'settings form' => 'ctools_string_settings_form', + 'context' => 'ctools_string_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter a value for this argument'), + ), + 'path placeholder' => 'ctools_string_path_placeholder', // This is in pagemanager. +); + +/** + * Discover if this argument gives us the term we crave. + */ +function ctools_string_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('string'); + } + + $context = ctools_context_create('string', $arg); + $context->original_argument = $arg; + + return $context; +} + +/** + * Settings form for the argument + */ +function ctools_string_settings_form(&$form, &$form_state, $conf) { + $form['settings']['use_tail'] = array( + '#title' => t('Get all arguments after this one'), + '#type' => 'checkbox', + '#default_value' => !empty($conf['use_tail']), + '#description' => t('If checked, this string will include all arguments. For example, if the path is "path/%" and the user visits "path/foo/bar", if this is not checked the string will be "foo". If it is checked the string will be "foo/bar".'), + ); +} + +/** + * Switch the placeholder based upon user settings. + */ +function ctools_string_path_placeholder($argument) { + if (empty($argument['settings']['use_tail'])) { + return '%pm_arg'; + } + else { + return '%pm_arg_tail'; + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/term.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/term.inc new file mode 100644 index 0000000000000000000000000000000000000000..feb39845b06b4d8c251d103f726ad50f12601988 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/term.inc @@ -0,0 +1,146 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a Taxonomy term + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Taxonomy term: ID"), + // keyword to use for %substitution + 'keyword' => 'term', + 'description' => t('Creates a single taxonomy term from a taxonomy ID or taxonomy term name.'), + 'context' => 'ctools_term_context', + 'default' => array('input_form' => 'tid', 'breadcrumb' => TRUE), + 'settings form' => 'ctools_term_settings_form', + 'placeholder form' => 'ctools_term_ctools_argument_placeholder', + 'breadcrumb' => 'ctools_term_breadcrumb', +); + +/** + * Discover if this argument gives us the term we crave. + */ +function ctools_term_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('term'); + } + + switch ($conf['input_form']) { + case 'tid': + default: + if (!is_numeric($arg)) { + return FALSE; + } + $term = taxonomy_get_term($arg); + break; + + case 'term': + $terms = taxonomy_get_term_by_name($arg); + + $conf['vids'] = is_array($conf['vids']) ? array_filter($conf['vids']) : NULL; + if ((count($terms) > 1) && isset($conf['vids'])) { + foreach ($terms as $potential) { + foreach ($conf['vids'] as $vid => $active) { + if ($active && $potential->vid == $vid) { + $term = $potential; + // break out of the foreaches AND the case + break 3; + } + } + } + } + $term = array_shift($terms); + break; + } + + if (empty($term)) { + return NULL; + } + + if (!empty($conf['vids']) && array_filter($conf['vids']) && empty($conf['vids'][$term->vid])) { + return NULL; + } + + $context = ctools_context_create('term', $term); + $context->original_argument = $arg; + return $context; +} + +/** + * Settings form for the argument + */ +function ctools_term_settings_form(&$form, &$form_state, $conf) { + // @todo allow synonym use like Views does. + $form['settings']['input_form'] = array( + '#title' => t('Argument type'), + '#type' => 'radios', + '#options' => array('tid' => t('Term ID'), 'term' => t('Term name')), + '#default_value' => $conf['input_form'], + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + + $vocabularies = taxonomy_get_vocabularies(); + $options = array(); + foreach ($vocabularies as $vid => $vocab) { + $options[$vid] = $vocab->name; + } + $form['settings']['vids'] = array( + '#title' => t('Limit to these vocabularies'), + '#type' => 'checkboxes', + '#options' => $options, + '#default_value' => !empty($conf['vids']) ? $conf['vids'] : array(), + '#description' => t('If no vocabularies are checked, terms from all vocabularies will be accepted.'), + ); + + $form['settings']['breadcrumb'] = array( + '#title' => t('Inject hierarchy into breadcrumb trail'), + '#type' => 'checkbox', + '#default_value' => !empty($conf['breadcrumb']), + '#description' => t('If checked, taxonomy term parents will appear in the breadcrumb trail.'), + ); +} + +/** + * Form fragment to get an argument to convert a placeholder for preview. + */ +function ctools_term_ctools_argument_placeholder($conf) { + switch ($conf['input_form']) { + case 'tid': + default: + return array( + '#type' => 'textfield', + '#description' => t('Enter a taxonomy term ID.'), + ); + case 'term': + return array( + '#type' => 'textfield', + '#description' => t('Enter a taxonomy term name.'), + ); + } +} + +/** + * Inject the breadcrumb trail if necessary. + */ +function ctools_term_breadcrumb($conf, $context) { + if (empty($conf['breadcrumb']) || empty($context->data) || empty($context->data->tid)) { + return; + } + + $breadcrumb = array(); + $current->tid = $context->data->tid; + while ($parents = taxonomy_get_parents($current->tid)) { + $current = array_shift($parents); + $breadcrumb[] = l($current->name, 'taxonomy/term/' . $current->tid); + } + + $breadcrumb = array_merge(drupal_get_breadcrumb(), array_reverse($breadcrumb)); + drupal_set_breadcrumb($breadcrumb); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/terms.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/terms.inc new file mode 100644 index 0000000000000000000000000000000000000000..05d75f491c91240c5f475649f035c5d722df89db --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/terms.inc @@ -0,0 +1,76 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a Taxonomy term + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Taxonomy term (multiple): ID"), + // keyword to use for %substitution + 'keyword' => 'term', + 'description' => t('Creates a group of taxonomy terms from a list of tids separated by a comma or a plus sign. In general the first term of the list will be used for panes.'), + 'context' => 'ctools_terms_context', + 'default' => array('breadcrumb' => TRUE), + 'settings form' => 'ctools_terms_settings_form', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter a term ID or a list of term IDs separated by a + or a ,'), + ), + 'breadcrumb' => 'ctools_terms_breadcrumb', +); + +/** + * Discover if this argument gives us the term we crave. + */ +function ctools_terms_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('terms'); + } + + $terms = ctools_break_phrase($arg); + if (empty($terms->value) || !empty($terms->invalid_input)) { + return FALSE; + } + + $context = ctools_context_create('terms', $terms); + $context->original_argument = $arg; + return $context; +} + +/** + * Settings form for the argument + */ +function ctools_terms_settings_form(&$form, &$form_state, $conf) { + $form['settings']['breadcrumb'] = array( + '#title' => t('Inject hierarchy of first term into breadcrumb trail'), + '#type' => 'checkbox', + '#default_value' => !empty($conf['breadcrumb']), + '#description' => t('If checked, taxonomy term parents will appear in the breadcrumb trail.'), + ); +} + +/** + * Inject the breadcrumb trail if necessary. + */ +function ctools_terms_breadcrumb($conf, $context) { + if (empty($conf['breadcrumb'])) { + return; + } + + $current->tid = $context->tids[0]; + $breadcrumb = array(); + while ($parents = taxonomy_get_parents($current->tid)) { + $current = array_shift($parents); + $breadcrumb[] = l($current->name, 'taxonomy/term/' . $current->tid); + } + + $breadcrumb = array_merge(drupal_get_breadcrumb(), array_reverse($breadcrumb)); + drupal_set_breadcrumb($breadcrumb); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/uid.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/uid.inc new file mode 100644 index 0000000000000000000000000000000000000000..0064ff3a5340cb46cbc86ef379a08d5890fa02b3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/uid.inc @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a user id + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("User: ID"), + // keyword to use for %substitution + 'keyword' => 'user', + 'description' => t('Creates a user context from a user ID argument.'), + 'context' => 'ctools_argument_uid_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the user ID of a user for this argument'), + ), + 'default' => array('to_arg' => TRUE), + 'path placeholder' => '%pm_uid_arg', // This is in pagemanager. + 'path placeholder to_arg' => TRUE, +); + +/** + * Discover if this argument gives us the user we crave. + */ +function ctools_argument_uid_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('user'); + } + + // We can accept either a node object or a pure nid. + if (is_object($arg)) { + return ctools_context_create('user', $arg); + } + + if (!is_numeric($arg)) { + return NULL; + } + + $account = user_load(array('uid' => $arg)); + if (!$account) { + return NULL; + } + + return ctools_context_create('user', $account); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/user_name.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/user_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..58c7f9c8b8e487b3813059f4008241f2a0c3a549 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/user_name.inc @@ -0,0 +1,47 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a username + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("User: name"), + // keyword to use for %substitution + 'keyword' => 'user', + 'description' => t('Creates a user context from a user name.'), + 'context' => 'ctools_argument_user_name_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the username of a user for this argument'), + ), +); + +/** + * Discover if this argument gives us the user we crave. + */ +function ctools_argument_user_name_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('user'); + } + + // We can accept either a node object or a pure nid. + if (is_object($arg)) { + return ctools_context_create('user', $arg); + } + + $account = user_load(array('name' => $arg)); + if (!$account) { + return NULL; + } + return ctools_context_create('user', $account); +} + + + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/vid.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/vid.inc new file mode 100644 index 0000000000000000000000000000000000000000..1b81347e49230a268a29667697ea14f7922db15f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/arguments/vid.inc @@ -0,0 +1,45 @@ +<?php + +/** + * @file + * + * Plugin to provide an argument handler for a vocabulary id + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Vocabulary: ID"), + // keyword to use for %substitution + 'keyword' => 'vocabulary', + 'description' => t('Creates a vocabulary context from a vocabulary ID argument.'), + 'context' => 'ctools_vid_context', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the vocabulary ID for this argument'), + ), +); + +/** + * Discover if this argument gives us the vocabulary we crave. + */ +function ctools_vid_context($arg = NULL, $conf = NULL, $empty = FALSE) { + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('vocabulary'); + } + + if (!is_numeric($arg)) { + return NULL; + } + + $vocabulary = taxonomy_vocabulary_load($arg); + if (!$vocabulary) { + return NULL; + } + + return ctools_context_create('vocabulary', $vocabulary); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/block.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/block.inc new file mode 100644 index 0000000000000000000000000000000000000000..30caaf99a9c438a6c7dfca7d12538d4df31b6700 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/block.inc @@ -0,0 +1,421 @@ +<?php + +/** + * @file + * Provide Drupal blocks as content. + * + * Since blocks don't provide all of the features we do, we have to do a little + * extra work, including providing icons and categories for core blocks. Blocks + * from contrib modules get to provide their own stuff, or get relegated to + * the old "Miscellaneous" category. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + // And this is just the administrative title. + // All our callbacks are named according to the standard pattern and can be deduced. + 'title' => t('Block'), + 'content type' => 'ctools_block_content_type_content_type', +); + +/** + * Return the block content types with the specified $subtype_id. + */ +function ctools_block_content_type_content_type($subtype_id) { + list($module, $delta) = explode('-', $subtype_id, 2); + $module_blocks = module_invoke($module, 'block', 'list'); + if (isset($module_blocks[$delta])) { + return _ctools_block_content_type_content_type($module, $delta, $module_blocks[$delta]); + } +} + +/** + * Return all block content types available. + * + * Modules wanting to make special adjustments the way that CTools handles their blocks + * can implement an extension to the hook_block() family, where the function name is + * of the form "$module . '_ctools_block_info'". + */ +function ctools_block_content_type_content_types() { + $types = array(); + foreach (module_list() as $module) { + $module_blocks = module_invoke($module, 'block', 'list'); + if ($module_blocks) { + foreach ($module_blocks as $delta => $block) { + $info = _ctools_block_content_type_content_type($module, $delta, $block); + // this check means modules can remove their blocks; particularly useful + // if they offer the block some other way (like we do for views) + if ($info) { + $types["$module-$delta"] = $info; + } + } + } + } + return $types; +} + +/** + * Return an info array for a specific block. + */ +function _ctools_block_content_type_content_type($module, $delta, $block) { + // strip_tags used because it goes through check_plain and that + // just looks bad. + $info = array( + 'title' => strip_tags($block['info']), + ); + + // Ask around for further information by invoking the hook_block() extension. + $function = $module . '_ctools_block_info'; + if (!function_exists($function)) { + $function = 'ctools_default_block_info'; + } + $function($module, $delta, $info); + + return $info; +} + +/** + * Output function for the 'block' content type. Outputs a block + * based on the module and delta supplied in the configuration. + */ +function ctools_block_content_type_render($subtype, $conf) { + list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf); + $block = (object) module_invoke($module, 'block', 'view', $delta); + + if (empty($block)) { + return; + } + + $block->module = $module; + $block->delta = $delta; + + // $block->title is not set for the blocks returned by block_block() (the + // Block module adds the title in block_list() instead), so we look it up + // manually, unless the title is overridden and does not use the %title + // placeholder. + if ($module == 'block' && (empty($conf['override_title']) || strpos($conf['override_title_text'], '%title') !== FALSE)) { + // {block}.title is plain text, but this hook should return an HTML title. + $block->subject = check_plain(db_result(db_query("SELECT title FROM {blocks} WHERE module = '%s' AND delta = '%s'", 'block', $delta))); + } + + if (isset($block->subject)) { + $block->title = $block->subject; + } + else { + $block->title = NULL; + } + + if (user_access('administer blocks')) { + $block->admin_links = array( + array( + 'title' => t('Configure block'), + 'alt' => t("Configure this block's 'block settings' in administer >> site building >> blocks"), + 'href' => "admin/build/block/configure/$module/$delta", + 'query' => drupal_get_destination(), + ), + ); + } + + // TEMP: Disabling block visibility checking. Ultimately we may be able to + // finally just say it's not supported. + return $block; + + // This seems extra but it prevents an unnecessary query sometimes. + if (empty($conf['block_visibility']) && $block->module != 'block') { + return $block; + } + + // Test for block visibility + + $result = db_query("SELECT title, pages, visibility FROM {blocks} WHERE module = '%s' AND delta = '%s'", $block->module, $block->delta); + $block_visibility = db_fetch_object($result); + + if ($block->module == 'block') { + // {block}.title is plain text, but this hook should return an HTML title. + $block->title = check_plain($block_visibility->title); + } + + if (empty($conf['block_visibility'])) { + return $block; + } + + if ($block_visibility && $block_visibility->pages) { + if ($block_visibility->visibility < 2) { + $path = drupal_get_path_alias($_GET['q']); + $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($block_visibility->pages, '/')) .')$/'; + $page_match = !($block_visibility->visibility xor preg_match($regexp, $path)); + } + else { + $page_match = drupal_eval($block_visibility->pages); + } + } + else { + $page_match = TRUE; + } + + if ($page_match) { + return $block; + } +} + +/** + * Empty form so we can have the default override title. + */ +function ctools_block_content_type_edit_form(&$form, &$form_state) { + // Does nothing! +} + +/** + * Submit function to fix the subtype for really old panel panes. + */ +function ctools_block_content_type_edit_form_submit(&$form, &$form_state) { + if (empty($form_state['subtype']) && isset($form_state['pane'])) { + $form_state['pane']->subtype = $form_state['conf']['module'] . '-' . $form_state['conf']['delta']; + unset($form_state['conf']['module']); + unset($form_state['conf']['delta']); + } +} + +/** + * Returns an edit form for a block. + */ +//function ctools_block_content_type_edit_form($id, $parents, $conf) { +// if (user_access('administer advanced pane settings')) { +// $form['block_visibility'] = array( +// '#type' => 'checkbox', +// '#title' => t('Use block visibility settings (see block config)'), +// '#default_value' => !empty($conf['block_visibility']), +// '#description' => t('If checked, the block visibility settings for this block will apply to this block.'), +// ); +// // Module-specific block configurations. +// if ($settings = module_invoke($module, 'block', 'configure', $delta)) { +// // Specifically modify a couple of core block forms. +// if ($module == 'block') { +// unset($settings['submit']); +// $settings['info']['#type'] = 'value'; +// $settings['info']['#value'] = $settings['info']['#default_value']; +// } +// ctools_admin_fix_block_tree($settings); +// $form['block_settings'] = array( +// '#type' => 'fieldset', +// '#title' => t('Block settings'), +// '#description' => t('Settings in this section are global and are for all blocks of this type, anywhere in the system.'), +// '#tree' => FALSE, +// ); +// +// +// $form['block_settings'] += $settings; +// } +// } +// +// return $form; +//} + +//function ctools_admin_submit_block(&$form_values) { +// if (!empty($form_values['block_settings'])) { +// module_invoke($form_values['module'], 'block', 'save', $form_values['delta'], $form_values['block_settings']); +// } +//} +// +///** +// * Because form api cannot collapse just part of a tree, and the block settings +// * assume no tree, we have to collapse the tree ourselves. +// */ +//function ctools_admin_fix_block_tree(&$form, $key = NULL) { +// if ($key) { +// if (!empty($form['#parents'])) { +// $form['#parents'] = array_merge(array('configuration', 'block_settings'), $form['#parents']); +// } +// else if (empty($form['#tree'])) { +// $form['#parents'] = array('configuration', 'block_settings', $key); +// } +// } +// +// if (isset($form['#type']) && $form['#type'] == 'textarea' && !empty($form['#rows']) && $form['#rows'] > 10) { +// $form['#rows'] = 10; +// } +// +// foreach (element_children($form) as $key) { +// ctools_admin_fix_block_tree($form[$key], $key); +// } +//} + +/** + * Returns the administrative title for a type. + */ +function ctools_block_content_type_admin_title($subtype, $conf) { + list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf); + $block = module_invoke($module, 'block', 'list'); + if (empty($block) || empty($block[$delta])) { + return t('Deleted/missing block @module-@delta', array('@module' => $module, '@delta' => $delta)); + } + + // The block description reported by hook_block() is plain text, but the title + // reported by this hook should be HTML. + $title = check_plain($block[$delta]['info']); + return $title; +} + +/** + * Output function for the 'block' content type. Outputs a block + * based on the module and delta supplied in the configuration. + */ +function ctools_block_content_type_admin_info($subtype, $conf) { + list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf); + $block = (object) module_invoke($module, 'block', 'view', $delta); + + // Sanitize the block because <script> tags can hose javascript up: + if (!empty($block->content)) { + $block->content = filter_xss_admin($block->content); + } + + if (!empty($block) && !empty($block->subject)) { + $block->title = $block->subject; + return $block; + } +} + +function _ctools_block_get_module_delta($subtype, $conf) { + if (strpos($subtype, '-')) { + return explode('-', $subtype, 2); + } + else { + return array($conf['module'], $conf['delta']); + } +} + +/** + * Provide default icon and categories for blocks when modules don't do this + * for us. + */ +function ctools_default_block_info($module, $delta, &$info) { + $core_modules = array('aggregator', 'block', 'blog', 'blogapi', 'book', 'color', 'comment', 'contact', 'drupal', 'filter', 'forum', 'help', 'legacy', 'locale', 'menu', 'node', 'path', 'ping', 'poll', 'profile', 'search', 'statistics', 'taxonomy', 'throttle', 'tracker', 'upload', 'user', 'watchdog', 'system'); + + if (in_array($module, $core_modules)) { + $info['icon'] = 'icon_core_block.png'; + $info['category'] = t('Miscellaneous'); + } + else { + $info['icon'] = 'icon_contrib_block.png'; + $info['category'] = t('Miscellaneous'); + } +} + +// These are all on behalf of modules that don't implement ctools but that +// we care about. +function menu_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_block_menu.png'; + $info['category'] = t('Menus'); + if ($delta == 'primary-links' || $delta == 'secondary-links') { + $info['icon'] = 'icon_core_primarylinks.png'; + } +} + +function forum_ctools_block_info($module, $delta, &$info) { + $info['category'] = t('Activity'); + switch ($delta) { + case '0': + $info['icon'] = 'icon_core_activeforumtopics.png'; + break; + + case '1': + $info['icon'] = 'icon_core_newforumtopics.png'; + break; + + default: + // safety net + ctools_default_block_info($module, $delta, $info); + } +} + +function profile_ctools_block_info($module, $delta, &$info) { + // Hide the author information block which isn't as rich as what we can + // do with context. + $info = NULL; +} + +function book_ctools_block_info($module, $delta, &$info) { + // Hide the book navigation block which isn't as rich as what we can + // do with context. + $info = NULL; +} + +function blog_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_recentblogposts.png'; + $info['category'] = t('Activity'); +} + +function poll_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_recentpoll.png'; + $info['category'] = t('Activity'); +} + +function comment_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_recentcomments.png'; + $info['category'] = t('Activity'); +} + +function search_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_searchform.png'; + $info['category'] = t('Widgets'); +} + +function node_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_syndicate.png'; + $info['category'] = t('Widgets'); +} + +function aggregator_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_syndicate.png'; + $info['category'] = t('Feeds'); +} + +function block_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_block_empty.png'; + $info['category'] = t('Miscellaneous'); +} + +function user_ctools_block_info($module, $delta, &$info) { + $info['category'] = t('Activity'); + switch ($delta) { + case '0': + $info['icon'] = 'icon_core_userlogin.png'; + $info['category'] = t('Widgets'); + break; + + case '1': + $info['icon'] = 'icon_core_navigation.png'; + $info['category'] = t('Menus'); + break; + + case '2': + $info['icon'] = 'icon_core_whosnew.png'; + break; + + case '3': + $info['icon'] = 'icon_core_whosonline.png'; + break; + + default: + // safety net + ctools_default_block_info($module, $delta, $info); + } +} + +function locale_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_languageswitcher.png'; + $info['category'] = t('Widgets'); +} + +function statistics_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_popularcontent.png'; + $info['category'] = t('Activity'); +} + +function system_ctools_block_info($module, $delta, &$info) { + $info['icon'] = 'icon_core_drupal.png'; + $info['category'] = t('Widgets'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_block.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_block.png new file mode 100644 index 0000000000000000000000000000000000000000..fa78ec179a83428e5b8e247890278cdf91a8cb3e Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_block.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_block_empty.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_block_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0891b03d97142074cabbe5ed47175ad01c838e Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_block_empty.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_menu.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..38cf72090abaa16000c9dceedee8196df1c5251e Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_menu.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_page.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_page.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2fa51d3856f366098978742cfe13e9389b487e Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_contrib_page.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_activeforumtopics.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_activeforumtopics.png new file mode 100644 index 0000000000000000000000000000000000000000..8414a8f8829be40a052814087e24c5800dcc6e4b Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_activeforumtopics.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_authorinformation.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_authorinformation.png new file mode 100644 index 0000000000000000000000000000000000000000..ab248f3f1bb62536bbf23296a949bfe05cd56bc7 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_authorinformation.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block.png new file mode 100644 index 0000000000000000000000000000000000000000..b0d9628adf19efed3b30c847a7511fc093d469b9 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block_empty.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..da08c64c64f2c6f7c5c34a442d4c1e3287f17053 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block_empty.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block_menu.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..84594431b705009714e569d99bf3a2739c42b7f5 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_block_menu.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_booknavigation.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_booknavigation.png new file mode 100644 index 0000000000000000000000000000000000000000..52dfca5369bfd5cabe1b46b7ab9ff54b7c8dc14c Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_booknavigation.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_languageswitcher.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_languageswitcher.png new file mode 100644 index 0000000000000000000000000000000000000000..dc4521fffadb3b58e0d6d8a4463e0f99ba17f4a7 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_languageswitcher.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_navigation.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_navigation.png new file mode 100644 index 0000000000000000000000000000000000000000..fb4c1f84f8261e47110d3414be92f9aa910c8646 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_navigation.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_newforumtopics.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_newforumtopics.png new file mode 100644 index 0000000000000000000000000000000000000000..70bbde26bbe02b474b610658a8a97f51707a4ea1 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_newforumtopics.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_page.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_page.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_page.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_popularcontent.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_popularcontent.png new file mode 100644 index 0000000000000000000000000000000000000000..70bbde26bbe02b474b610658a8a97f51707a4ea1 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_popularcontent.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_primarylinks.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_primarylinks.png new file mode 100644 index 0000000000000000000000000000000000000000..6dafb99ed084232acc18dfccb2b8f8327051245a Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_primarylinks.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentblogposts.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentblogposts.png new file mode 100644 index 0000000000000000000000000000000000000000..785207ac49e311f1716220982f79afe382c861bb Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentblogposts.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentcomments.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentcomments.png new file mode 100644 index 0000000000000000000000000000000000000000..ba96e32a31863c59c6ecab8df957c0da95437532 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentcomments.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentpoll.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentpoll.png new file mode 100644 index 0000000000000000000000000000000000000000..c23fa23e65cc833643971cf2fe2bdbbb0a800348 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_recentpoll.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_searchform.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_searchform.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad1deb65c4a1cada8cdedb7619f3ed5e8ff0587 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_searchform.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_syndicate.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_syndicate.png new file mode 100644 index 0000000000000000000000000000000000000000..27c54bf00c8ef49996f633cef4f998aa6445833b Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_syndicate.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_userlogin.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_userlogin.png new file mode 100644 index 0000000000000000000000000000000000000000..dc4521fffadb3b58e0d6d8a4463e0f99ba17f4a7 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_userlogin.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_whosnew.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_whosnew.png new file mode 100644 index 0000000000000000000000000000000000000000..51303e7fae68ef81eb001d8231f486bcf02afee2 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_whosnew.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_whosonline.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_whosonline.png new file mode 100644 index 0000000000000000000000000000000000000000..a5896e3a54bbe148beddc5ef31aa4f93329b60a2 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/block/icon_core_whosonline.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/contact.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/contact.inc new file mode 100644 index 0000000000000000000000000000000000000000..86038144f0852ce556079fa82317e91311063ac7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/contact.inc @@ -0,0 +1,59 @@ +<?php + +if (module_exists('contact')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Contact form'), + 'icon' => 'icon_contact.png', + 'description' => t('The site contact form that allows users to send a message to site administrators.'), + 'category' => t('Widgets'), + ); +} + +/** + * Render the custom content type. + */ +function ctools_contact_content_type_render($subtype, $conf, $panel_args, $context) { + if (!user_access('access site-wide contact form')) { + return; + } + // Build the content type block. + $block = new stdClass(); + $block->module = 'contact'; + $block->delta = 'form'; + $block->title = t('Contact'); + + module_load_include('inc', 'contact', 'contact.pages'); + $block->content = contact_site_page(); + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_contact_content_type_edit_form(&$form, &$form_state) { + // Empty so that we can have title override. +} + +/** + * Submit handler for contact form. + */ +function ctools_contact_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. +/* + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +*/ +} + +/** + * Returns the administrative title for a type. + */ +function ctools_contact_content_type_admin_title($subtype, $conf, $context) { + return t('Contact form'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/icon_contact.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/icon_contact.png new file mode 100644 index 0000000000000000000000000000000000000000..ab248f3f1bb62536bbf23296a949bfe05cd56bc7 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/icon_contact.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/user_contact.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/user_contact.inc new file mode 100644 index 0000000000000000000000000000000000000000..7f006f584e9903b670844431ba73698a7ca2ce33 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/contact/user_contact.inc @@ -0,0 +1,65 @@ +<?php + +if (module_exists('contact')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('User contact form'), + 'icon' => 'icon_contact.png', + 'description' => t('The site contact form that allows users to contact other users.'), + 'category' => t('User'), + 'required context' => new ctools_context_required(t('User'), 'user'), + ); +} + +/** + * Render the custom content type. + */ +function ctools_user_contact_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + if (!_contact_user_tab_access($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'contact'; + $block->delta = 'form'; + $block->title = t('Contact @name', array('@name' => $context->data->name)); + + module_load_include('inc', 'contact', 'contact.pages'); + $block->content = contact_user_page($context->data); + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_user_contact_content_type_edit_form(&$form, &$form_state) { + // Empty so that we can have title override. +} + +/** + * Submit handler for contact form. + */ +function ctools_user_contact_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. +/* + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +*/ +} + +/** + * Returns the administrative title for a type. + */ +function ctools_user_contact_content_type_admin_title($subtype, $conf, $context) { + return t('User contact form'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/custom/custom.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/custom/custom.inc new file mode 100644 index 0000000000000000000000000000000000000000..c4a45be147a98fd8dfcd67919f21242b91260190 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/custom/custom.inc @@ -0,0 +1,413 @@ +<?php + +/** + * @file + * Custom content type. + * + * This content type is nothing more than a title and a body that is entered + * by the user and run through standard filters. The information is stored + * right in the config, so each custom content is unique. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Custom content'), + 'no title override' => TRUE, + 'defaults' => array('admin_title' => '', 'title' => '', 'body' => '', 'format' => FILTER_FORMAT_DEFAULT, 'substitute' => TRUE), + 'js' => array('misc/autocomplete.js', 'misc/textarea.js', 'misc/collapse.js'), + // Make sure the edit form is only used for some subtypes. + 'edit form' => '', + 'add form' => '', + 'edit text' => t('Edit'), + 'all contexts' => TRUE, +); + +/** + * Return the custom content types with the specified $subtype_id. + */ +function ctools_custom_content_type_content_type($subtype_id) { + if ($subtype_id == 'custom') { + return _ctools_default_content_type_content_type(); + } + else { + ctools_include('export'); + $content = ctools_export_crud_load('ctools_custom_content', $subtype_id); + if ($content) { + return _ctools_custom_content_type_content_type($content); + } + } +} + +/** + * Return all custom content types available. + */ +function ctools_custom_content_type_content_types() { + ctools_include('export'); + $types = array(); + $types['custom'] = _ctools_default_content_type_content_type(); + + foreach (ctools_export_crud_load_all('ctools_custom_content') as $name => $content) { + $types[$name] = _ctools_custom_content_type_content_type($content); + } + return $types; +} + +/** + * Settings for the default custom content type. + * + * The default is the one that allows the user to actually create a type. + */ +function _ctools_default_content_type_content_type() { + $info = array( + 'name' => 'custom', + 'title' => t('New custom content'), + 'top level' => TRUE, + 'category' => t('Custom'), + 'description' => t('Create a completely custom piece of HTML content.'), + 'edit form' => 'ctools_custom_content_type_edit_form', + 'all contexts' => TRUE, + 'check editable' => 'ctools_custom_content_type_editable', + ); + + return $info; +} + +/** + * Return an info array for a specific custom content type. + */ +function _ctools_custom_content_type_content_type($content) { + $info = array( + 'name' => $content->name, + 'title' => check_plain($content->admin_title), + 'description' => check_plain($content->admin_description), + 'category' => $content->category ? check_plain($content->category) : t('Miscellaneous'), + 'all contexts' => TRUE, + 'icon' => 'icon_block_custom.png', + // Store this here to make it easy to access. + 'content' => $content, + ); + + return $info; +} + +/** + * Given a subtype and a $conf, return the actual settings to use. + * + * The actual settings may be stored directly in the pane or this may + * be a pointer to re-usable content that may be in the database or in + * an export. We have to determine from the subtype whether or not it + * is local or shared custom content. + */ +function ctools_custom_content_type_get_conf($subtype, $conf) { + if ($subtype['name'] != 'custom') { + $settings = $subtype['content']->settings; + $settings['custom_type'] = 'fixed'; + $settings['content'] = $subtype['content']; + } + else { + // This means they created it as custom content and then set it as + // reusable. Since we're not allowed to change the subtype, we're + // still stored as though we are local, but are pointing off to + // non-local. + if (!empty($conf['name'])) { + ctools_include('export'); + $content = ctools_export_crud_load('ctools_custom_content', $conf['name']); + if ($content) { + $settings = $content->settings; + $settings['custom_type'] = 'fixed'; + $settings['content'] = $content; + $settings['admin_title'] = $content->admin_title; + } + else { + $content = ctools_export_crud_new('ctools_custom_content'); + $content->name = $conf['name']; + $settings = array( + 'admin_title' => t('Missing/deleted content'), + 'title' => '', + 'body' => '', + 'format' => FILTER_FORMAT_DEFAULT, + 'substitute' => TRUE, + 'custom_type' => 'fixed', + 'content' => $content, + ); + } + } + // This means that it is created as custom and has not been set to + // reusable. + else { + $settings = $conf; + $settings['custom_type'] = 'local'; + } + } + + return $settings; +} + +function ctools_custom_content_type_editable($content_type, $subtype, $conf) { + if ($subtype['name'] == 'custom' && !empty($conf['name'])) { + return FALSE; + } + + return TRUE; +} + +/** + * Output function for the 'custom' content type. Outputs a custom + * based on the module and delta supplied in the configuration. + */ +function ctools_custom_content_type_render($subtype, $conf, $args, $contexts) { + $settings = ctools_custom_content_type_get_conf(ctools_custom_content_type_content_type($subtype), $conf); + + static $delta = 0; + + $block = new stdClass(); + $block->subtype = ++$delta; + $block->title = filter_xss_admin($settings['title']); + + // Add keyword substitutions if we were configured to do so. + $content = $settings['body']; + if (!empty($contexts) && !empty($settings['substitute'])) { + $content = ctools_context_keyword_substitute($content, array(), $contexts); + } + + if ($settings['custom_type'] == 'fixed' && user_access('administer custom content')) { + $block->admin_links = array( + array( + 'title' => t('Configure content pane'), + 'alt' => t("Configure this pane in administer >> site building >> custom content panes"), + 'href' => 'admin/build/ctools-content/list/' . $settings['content']->name . '/edit', + 'query' => drupal_get_destination(), + ), + ); + } + + $block->content = check_markup($content, $settings['format'], FALSE); + return $block; +} + +/** + * Callback to provide the administrative title of the custom content. + */ +function ctools_custom_content_type_admin_title($subtype, $conf) { + $settings = ctools_custom_content_type_get_conf(ctools_custom_content_type_content_type($subtype), $conf); + + $output = t('Custom'); + $title = !empty($settings['admin_title']) ? $settings['admin_title'] : $settings['title']; + if ($title) { + if ($settings['custom_type'] != 'fixed') { + $output = t('Custom: @title', array('@title' => $title)); + } + else { + $output = $title; + } + } + + return $output; +} + +/** + * Callback to provide administrative info. In this case we'll render the + * content as long as it's not PHP, which is too risky to render here. + */ +function ctools_custom_content_type_admin_info($subtype, $conf) { + $settings = ctools_custom_content_type_get_conf(ctools_custom_content_type_content_type($subtype), $conf); + + $block = new stdClass(); + $block->title = filter_xss_admin($settings['title']); + // We don't want to render php output on preview here, because if something is + // wrong the whole display will be borked. So we check to see if the php + // evaluator filter is being used, and make a temporary change to the filter + // so that we get the printed php, not the eval'ed php. + $php_filter = FALSE; + foreach (filter_list_format($settings['format']) as $filter) { + if ($filter->module == 'php') { + $php_filter = TRUE; + break; + } + } + // If a php filter is active, just print the source, but only if the current + // user has access to the actual filter. + if ($php_filter) { + if (!filter_access($settings['format'])) { + return NULL; + } + $block->content = '<pre>'. check_plain($settings['body']) .'</pre>'; + } + else { + // We also need to filter through XSS admin because <script> tags can + // cause javascript which will interfere with our ajax. + $block->content = filter_xss_admin(check_markup($settings['body'], $settings['format'])); + } + return $block; +} + +/** + * Returns an edit form for the custom type. + */ +function ctools_custom_content_type_edit_form(&$form, &$form_state) { + $settings = ctools_custom_content_type_get_conf($form_state['subtype'], $form_state['conf']); + $form_state['settings'] = $settings; + + if ($settings['custom_type'] == 'fixed') { + return; // no form for this case. + } + + $form['admin_title'] = array( + '#type' => 'textfield', + '#default_value' => isset($settings['admin_title']) ? $settings['admin_title'] : '', + '#title' => t('Administrative title'), + '#description' => t('This title will be used administratively to identify this pane. If blank, the regular title will be used.'), + ); + + $form['title'] = array( + '#type' => 'textfield', + '#default_value' => $settings['title'], + '#title' => t('Title'), + ); + + $form['body_field']['body'] = array( + '#title' => t('Body'), + '#type' => 'textarea', + '#default_value' => $settings['body'], + ); + $parents[] = 'format'; + $form['body_field']['format'] = filter_form($settings['format'], 1, $parents); + + if (!empty($form_state['contexts'])) { + // Set extended description if both CCK and Token modules are enabled, notifying of unlisted keywords + if (module_exists('content') && module_exists('token')) { + $description = t('If checked, context keywords will be substituted in this content. Note that CCK fields may be used as keywords using patterns like <em>%node:field_name-formatted</em>.'); + } elseif (!module_exists('token')) { + $description = t('If checked, context keywords will be substituted in this content. More keywords will be available if you install the Token module, see http://drupal.org/project/token.'); + } else { + $description = t('If checked, context keywords will be substituted in this content.'); + } + + $form['substitute'] = array( + '#type' => 'checkbox', + '#title' => t('Use context keywords'), + '#description' => $description, + '#default_value' => !empty($settings['substitute']), + ); + $form['contexts'] = array( + '#title' => t('Substitutions'), + '#type' => 'fieldset', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $rows = array(); + foreach ($form_state['contexts'] as $context) { + foreach (ctools_context_get_converters('%' . check_plain($context->keyword) . ':', $context) as $keyword => $title) { + $rows[] = array( + check_plain($keyword), + t('@identifier: @title', array('@title' => $title, '@identifier' => $context->identifier)), + ); + } + } + $header = array(t('Keyword'), t('Value')); + $form['contexts']['context'] = array('#value' => theme('table', $header, $rows)); + } + + if (!user_access('administer custom content') || !module_exists('ctools_custom_content')) { + return; + } + + // Make the other form items dependent upon it. + ctools_include('dependent'); + ctools_add_js('dependent'); + + $form['reusable'] = array( + '#type' => 'checkbox', + '#title' => t('Make this content reusable'), + '#default_value' => FALSE, + ); + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Machine name'), + '#description' => t('The machine readable name of this content. It must be unique, and it must contain only alphanumeric characters and underscores. Once created, you will not be able to change this value!'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-reusable' => array(1)), + ); + + $form['category'] = array( + '#type' => 'textfield', + '#title' => t('Category'), + '#description' => t('What category this content should appear in. If left blank the category will be "Miscellaneous".'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-reusable' => array(1)), + ); + + $form['admin_description'] = array( + '#type' => 'textarea', + '#title' => t('Administrative description'), + '#description' => t('A description of what this content is, does or is for, for administrative use.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-reusable' => array(1)), + ); +} + +function _ctools_custom_content_type_edit_save(&$content, $form_state) { + // Apply updates to the content object. + $content->category = $form_state['values']['category']; + $content->admin_title = $form_state['values']['admin_title']; + $content->admin_description = $form_state['values']['admin_description']; + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + if (isset($form_state['values'][$key])) { + $content->settings[$key] = $form_state['values'][$key]; + } + } + + ctools_export_crud_save('ctools_custom_content', $content); +} + +/** + * The validate form to ensure the custom content data is okay. + */ +function ctools_custom_content_type_edit_form_validate(&$form, &$form_state) { + if ($form_state['settings']['custom_type'] != 'fixed' && !empty($form_state['values']['reusable'])) { + if (empty($form_state['values']['name'])) { + form_error($form['name'], t('Name is required.')); + } + + // Check for string identifier sanity + if (!preg_match('!^[a-z0-9_]+$!', $form_state['values']['name'])) { + form_error($form['name'], t('The name can only consist of lowercase letters, underscores, and numbers.')); + return; + } + + // Check for name collision + if ($form_state['values']['name'] == 'custom' || (ctools_export_crud_load('ctools_custom_content', $form_state['values']['name']))) { + form_error($form['name'], t('Content with this name already exists. Please choose another name or delete the existing item before creating a new one.')); + } + } +} + +/** + * The submit form stores the data in $conf. + */ +function ctools_custom_content_type_edit_form_submit(&$form, &$form_state) { + if ($form_state['settings']['custom_type'] == 'fixed') { + _ctools_custom_content_type_edit_save($form_state['settings']['content'], $form_state); + } + // If the 'reusable' checkbox was checked, we will create a new + // custom content and give it the proper values. + else if (!empty($form_state['values']['reusable'])) { + $content = ctools_export_crud_new('ctools_custom_content'); + $content->name = $form_state['values']['name']; + _ctools_custom_content_type_edit_save($content, $form_state); + $form_state['conf']['name'] = $content->name; + } + else { + // Otherwise, just save values into $conf normally. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + if (isset($form_state['values'][$key])) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/custom/icon_block_custom.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/custom/icon_block_custom.png new file mode 100644 index 0000000000000000000000000000000000000000..bbde4bd57c4731ddcb109da8aed4398bc587a8fd Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/custom/icon_block_custom.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/form/form.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/form/form.inc new file mode 100644 index 0000000000000000000000000000000000000000..15bb90906bd14bdb5dfcef2570f8dc02d0422a9b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/form/form.inc @@ -0,0 +1,55 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + // only provides a single content type + 'single' => TRUE, + 'render last' => TRUE, + 'title' => t('General form'), + 'icon' => 'icon_form.png', + 'description' => t('Everything in the form that is not displayed by other content.'), + 'required context' => new ctools_context_required(t('Form'), 'form'), + 'category' => t('Form'), +); + +/** + * Output function for the 'node' content type. Outputs a node + * based on the module and delta supplied in the configuration. + */ +function ctools_form_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = 'form'; + + if (isset($context->form)) { + $block->title = $context->form_title; + if (!empty($context->form_id)) { + // If this is a form, drupal_render it. + $block->content = drupal_render($context->form); + } + else { + // Otherwise just spit back what we were given. This is probably an + // error message or something. + $block->content = $context->form; + } + $block->delta = $context->form_id; + } + else { + $block->title = t('Form'); + $block->content = t('Form goes here.'); + $block->delta = 'unknown'; + } + + return $block; +} + +function ctools_form_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" base form', array('@s' => $context->identifier)); +} + +function ctools_form_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to override title + // and stuff. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/form/icon_form.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/form/icon_form.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/form/icon_form.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node/icon_node.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node/icon_node.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node/icon_node.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node/node.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node/node.inc new file mode 100644 index 0000000000000000000000000000000000000000..a1507a59ef4a6f517387ac7c7e97609b390dafbf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node/node.inc @@ -0,0 +1,267 @@ +<?php + +/** + * @file + * Plugin to handle the 'node' content type which allows individual nodes + * to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Node'), + 'single' => TRUE, + 'defaults' => array( + 'nid' => '', + 'links' => TRUE, + 'leave_node_title' => FALSE, + 'identifier' => '', + 'build_mode' => 'teaser', + ), + 'title' => t('Existing node'), + 'icon' => 'icon_node.png', + 'description' => t('Add a node from your site as content.'), + 'category' => t('Custom'), + 'top level' => TRUE, + 'js' => array('misc/autocomplete.js'), +); + +/** + * Output function for the 'node' content type. + * + * Outputs a node based on the module and delta supplied in the configuration. + */ +function ctools_node_content_type_render($subtype, $conf, $panel_args) { + $nid = $conf['nid']; + $block = new stdClass(); + + foreach (explode('/', $_GET['q']) as $id => $arg) { + $nid = str_replace("%$id", $arg, $nid); + } + + foreach ($panel_args as $id => $arg) { + if (is_string($arg)) { + $nid = str_replace("@$id", $arg, $nid); + } + } + + // Support node translation + if (module_exists('translation')) { + if ($translations = module_invoke('translation', 'node_get_translations', $nid)) { + if ($translations[$GLOBALS['language']->language]) { + $nid = $translations[$GLOBALS['language']->language]->nid; + } + } + } + + if (!is_numeric($nid)) { + return; + } + + $node = node_load($nid); + if (!node_access('view', $node)) { + return; + } + + if (node_access('update', $node)) { + $block->admin_links['update'] = array( + 'title' => t('Edit node'), + 'alt' => t("Edit this node"), + 'href' => "node/$node->nid/edit", + 'query' => drupal_get_destination(), + ); + } + + $block->module = 'node'; + $block->delta = $node->nid; + + // Set block->title to the plain node title, then additionally set block->title_link to + // the node url if required. The actual link is rendered in ctools_content_render(). + $block->title = check_plain($node->title); + if (!empty($conf['link_node_title'])) { + $block->title_link = 'node/' . $node->nid; + } + + if (empty($conf['leave_node_title'])) { + $node->title = NULL; + } + + if (!empty($conf['identifier'])) { + $node->panel_identifier = $conf['identifier']; + } + + // Handle existing configurations with the deprecated 'teaser' option. + if (isset($conf['teaser'])) { + $conf['build_mode'] = $conf['teaser'] ? 'teaser' : 'full'; + } + + if (!isset($node->build_mode)) { + $node->build_mode = ($conf['build_mode'] == 'teaser' || $conf['build_mode'] == 'full') ? NODE_BUILD_NORMAL : $conf['build_mode']; + } + + $block->content = node_view($node, $conf['build_mode'] == 'teaser', FALSE, $conf['links']); + return $block; +} + +/** + * The form to add or edit a node as content. + */ +function ctools_node_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['leave_node_title'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($conf['leave_node_title']), + '#title' => t('Leave node title'), + '#description' => t('Advanced: if checked, do not touch the node title; this can cause the node title to appear twice unless your theme is aware of this.'), + ); + + $form['link_node_title'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($conf['link_node_title']), + '#title' => t('Link the node title to the node'), + '#description' => t('Check this box if you would like your pane title to link to the node.'), + ); + + + if ($form_state['op'] == 'add') { + $form['nid'] = array( + '#prefix' => '<div class="no-float">', + '#title' => t('Enter the title or NID of a node'), + '#description' => t('To use a NID from the URL, you may use %0, %1, ..., %N to get URL arguments. Or use @0, @1, @2, ..., @N to use arguments passed into the panel.'), + '#type' => 'textfield', + '#maxlength' => 512, + '#autocomplete_path' => 'ctools/autocomplete/node', + '#weight' => -10, + '#suffix' => '</div>', + ); + } + else { + $form['nid'] = array( + '#type' => 'value', + '#value' => $conf['nid'], + ); + } + + $form['links'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['links'], + '#title' => t('Include node links for "add comment", "read more" etc.'), + ); + + $form['identifier'] = array( + '#type' => 'textfield', + '#default_value' => !empty($conf['identifier']) ? $conf['identifier'] : '', + '#title' => t('Template identifier'), + '#description' => t('This identifier will be added as a template suggestion to display this node: node-panel-IDENTIFIER.tpl.php. Please see the Drupal theming guide for information about template suggestions.'), + ); + + // CCK holds the registry of available build modes, but can hardly + // push them as options for the build mode options, so we break the normal + // rule of not directly relying on non-core modules. + if ($modes = module_invoke('content', 'build_modes')) { + $build_mode_options = array(); + foreach ($modes as $key => $value) { + if (isset($value['views style']) && $value['views style']) { + $build_mode_options[$key] = $value['title']; + } + } + } + else { + $build_mode_options = array( + 'teaser' => t('Teaser'), + 'full' => t('Full node') + ); + } + + // Handle existing configurations with the deprecated 'teaser' option. + // Also remove the teaser key from the form_state. + if (isset($conf['teaser']) || !isset($conf['build_mode'])) { + unset($form_state['conf']['teaser']); + $conf['build_mode'] = $conf['teaser'] ? 'teaser' : 'full'; + } + $form['build_mode'] = array( + '#title' => t('Build mode'), + '#type' => 'select', + '#description' => t('Select a build mode for this node.'), + '#options' => $build_mode_options, + '#default_value' => $conf['build_mode'], + ); + +} + +/** + * Validate the node selection. + */ +function ctools_node_content_type_edit_form_validate(&$form, &$form_state) { + if ($form_state['op'] != 'add') { + return; + } + + $nid = $form_state['values']['nid']; + $preg_matches = array(); + $match = preg_match('/\[nid: (\d+)\]/', $nid, $preg_matches); + if (!$match) { + $match = preg_match('/^nid: (\d+)/', $nid, $preg_matches); + } + + if ($match) { + $nid = $preg_matches[1]; + } + if (is_numeric($nid)) { + $node = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.status FROM {node} n WHERE n.nid = %d"), $nid)); + } + else { + $node = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.status FROM {node} n WHERE LOWER(n.title) = LOWER('%s')"), $nid)); + } + if ($node) { + $form_state['values']['nid'] = $node->nid; + } + + if (!($node || preg_match('/^[@%]\d+$/', $nid)) || + // Do not allow unpublished nodes to be selected by unprivileged users + (empty($node->status) && !user_access('administer nodes'))) { + form_error($form['nid'], t('Invalid node')); + } +} + +/** + * Validate the node selection. + */ +function ctools_node_content_type_edit_form_submit(&$form, &$form_state) { + foreach (array('nid', 'links', 'leave_node_title', 'link_node_title', 'identifier', 'build_mode') as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a node. + */ +function ctools_node_content_type_admin_title($subtype, $conf) { + if (!is_numeric($conf['nid'])) { + return t('Node loaded from @var', array('@var' => $conf['nid'])); + } + + $node = node_load($conf['nid']); + if ($node) { + if (!empty($data->status) || user_access('administer nodes')) { + return check_plain($node->title); + } + else { + return t('Unpublished node @nid', array('@nid' => $conf['nid'])); + } + } + else { + return t('Deleted/missing node @nid', array('@nid' => $conf['nid'])); + } +} + +/** + * Display the administrative information for a node pane. + */ +function ctools_node_content_type_admin_info($subtype, $conf) { + // Just render the node. + return ctools_node_content_type_render($subtype, $conf, array()); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/icon_node.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/icon_node.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/icon_node.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_attachments.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_attachments.inc new file mode 100644 index 0000000000000000000000000000000000000000..85db862bc4a9a288ae2282ee9fe5b5c397c8e831 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_attachments.inc @@ -0,0 +1,43 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Attached files'), + 'icon' => 'icon_node.png', + 'description' => t('A list of files attached to the node.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), +); + +function ctools_node_attachments_content_type_render($subtype, $conf, $panel_args, $context) { + $node = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'attachments'; + + $block->title = t('Attached files'); + if ($node) { + if (!empty($node->files)) { + $block->content = theme('upload_attachments', $node->files); + } + $block->delta = $node->nid; + } + else { + $block->content = t('Attached files go here.'); + $block->delta = 'unknown'; + } + + return $block; +} + +function ctools_node_attachments_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" attachments', array('@s' => $context->identifier)); +} + +function ctools_node_attachments_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_author.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_author.inc new file mode 100644 index 0000000000000000000000000000000000000000..80aeec9e7eb8877160d61a875f178ca6d6a29a7c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_author.inc @@ -0,0 +1,69 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node author'), + 'icon' => 'icon_node.png', + 'description' => t('The author of the referenced node.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array( + 'link' => TRUE, + ), +); + +/** + * Render the custom content type. + */ +function ctools_node_author_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Get a shortcut to the node. + $node = $context->data; + + // Build the content type block. + $block = new stdClass(); + $block->module = 'node_author'; + $block->title = t('Author'); + $block->content = !empty($conf['link']) ? theme('username', $node) : check_plain($node->name ? $node->name : variable_get('anonymous', t('Anonymous'))); + $block->delta = $node->nid; + + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_node_author_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['link'] = array( + '#title' => t('Link to author profile'), + '#type' => 'checkbox', + '#default_value' => $conf['link'], + '#description' => t('Check here to link to the node author profile.'), + ); +} + +/** + * Submit handler for the custom type settings form. + */ +function ctools_node_author_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a type. + */ +function ctools_node_author_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" author', array('@s' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_body.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_body.inc new file mode 100644 index 0000000000000000000000000000000000000000..1ca320521b614fe0cfccc4919fe8f3d6e51694f8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_body.inc @@ -0,0 +1,59 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node body'), + 'icon' => 'icon_node.png', + 'description' => t('The body of the referenced node.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), +); + +/** + * Render the custom content type. + */ +function ctools_node_body_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Get a shortcut to the node. + $node = $context->data; + + // Load information about the node type. + $type = node_get_types('type', $node->type); + + // Do not render if the body is disabled for this node type. + if (!$type->has_body) { + return; + } + + $body = str_replace('<!--break-->', '', $node->body); + + // Build the content type block. + $block = new stdClass(); + $block->module = 'node_body'; + $block->title = $type->body_label; + $block->content = check_markup($body, $node->format, FALSE); + $block->delta = $node->nid; + + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_node_body_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} + +/** + * Returns the administrative title for a type. + */ +function ctools_node_body_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" body', array('@s' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_book_children.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_book_children.inc new file mode 100644 index 0000000000000000000000000000000000000000..64a36b73a2c4612c9a2e69db14d10ea474c240f4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_book_children.inc @@ -0,0 +1,42 @@ +<?php + +if (module_exists('book')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Book children'), + 'icon' => 'icon_node.png', + 'description' => t('The children menu the book the node belongs to.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + ); +} + +function ctools_node_book_children_content_type_render($subtype, $conf, $panel_args, $context) { + $node = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'book_children'; + + $block->title = t('Book children'); + if ($node) { + $block->content = isset($node->book) ? book_children($node->book) : ''; + $block->delta = $node->nid; + } + else { + $block->content = t('Book children menu goes here.'); + $block->delta = 'unknown'; + } + + return $block; +} + +function ctools_node_book_children_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" book children', array('@s' => $context->identifier)); +} + +function ctools_node_book_children_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_book_nav.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_book_nav.inc new file mode 100644 index 0000000000000000000000000000000000000000..b489af587634786a7a40ef05a6a1cb5926c8d2bd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_book_nav.inc @@ -0,0 +1,42 @@ +<?php + +if (module_exists('book')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Book navigation'), + 'icon' => 'icon_node.png', + 'description' => t('The navigation menu the book the node belongs to.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + ); +} + +function ctools_node_book_nav_content_type_render($subtype, $conf, $panel_args, $context) { + $node = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'book_nav'; + + $block->title = t('Book navigation'); + if ($node) { + $block->content = isset($node->book) ? theme('book_navigation', $node->book) : ''; + $block->delta = $node->nid; + } + else { + $block->content = t('Book navigation goes here.'); + $block->delta = 'unknown'; + } + + return $block; +} + +function ctools_node_book_nav_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" book navigation', array('@s' => $context->identifier)); +} + +function ctools_node_book_nav_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_comment_form.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_comment_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..5ed6514c1a1fa5c14712dea49d1fb86a1a2c594a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_comment_form.inc @@ -0,0 +1,89 @@ +<?php + +if (module_exists('comment')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Comment form'), + 'icon' => 'icon_node.png', + 'description' => t('A form to add a new comment.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array('anon_links' => false), + ); +} + +function ctools_node_comment_form_content_type_render($subtype, $conf, $panel_args, $context) { + $node = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'comments'; + $block->delta = $node->nid; + + $block->title = t('Add comment'); + + if (empty($node)) { + $block->content = t('Comment form here.'); + } + else { + if (user_access('post comments') && node_comment_mode($node->nid) == COMMENT_NODE_READ_WRITE) { + ctools_include('form'); + $form_state = array( + 'ctools comment alter' => TRUE, + 'node' => $node, + 'args' => array(array('nid' => $node->nid)) + ); + $block->content = ctools_build_form('comment_form', $form_state); + } + else if (!empty($conf['anon_links'])) { + $block->content = theme('comment_post_forbidden', $node); + } + } + + return $block; +} + +function ctools_node_comment_form_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" comment form', array('@s' => $context->identifier)); +} + +function ctools_node_comment_form_content_type_edit_form(&$form, &$form_state) { + $form['anon_links'] = array( + '#type' => 'checkbox', + '#title' => t('Shows links to register or login.'), + '#description' => t('If anonymous comments are not allowed, this will display the register and login links.'), + '#default_value' => $form_state['conf']['anon_links'], + ); +} + +function ctools_node_comment_form_content_type_edit_form_submit(&$form, &$form_state) { + // For each part of the form defined in the 'defaults' array set when you + // defined the content type, copy the value from the form into the array + // of items to be saved. We don't ever want to use + // $form_state['conf'] = $form_state['values'] because values contains + // buttons, form id and other items we don't want stored. CTools will handle + // the actual form submission. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Alter the comment form to get a little more control over it. + */ +function ctools_form_comment_form_alter(&$form, &$form_state) { + if (!empty($form_state['ctools comment alter'])) { + // Force the form to post back to wherever we are. + $form['#action'] = url($_GET['q'], array('fragment' => 'comment-form')); + if (empty($form['#submit'])) { + $form['#submit'] = array('comment_form_submit'); + } + $form['#submit'][] = 'ctools_node_comment_form_submit'; + } +} + +function ctools_node_comment_form_submit(&$form, &$form_state) { + $form_state['redirect'][0] = $_GET['q']; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_comments.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_comments.inc new file mode 100644 index 0000000000000000000000000000000000000000..8b1c13e6aad2f65201c1dcee1ab7910da4e561b4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_comments.inc @@ -0,0 +1,191 @@ +<?php + +if (module_exists('comment')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Node comments'), + 'icon' => 'icon_node.png', + 'description' => t('The comments of the referenced node.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array( + 'mode' => variable_get('comment_default_mode', COMMENT_MODE_THREADED_EXPANDED), + 'order' => variable_get('comment_default_order', COMMENT_ORDER_NEWEST_FIRST), + 'comments_per_page' => variable_get('comment_default_per_page', '50'), + 'anchor' => 1, + ), + ); +} + +function ctools_node_comments_content_type_render($subtype, $conf, $panel_args, $context) { + $node = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'comments'; + $block->delta = $node->nid; + + $block->title = t('Comments'); + if (empty($node)) { + $block->content = t('Node comments go here.'); + } + else if ($node->comment) { + $block->content = ctools_comment_render($node, $conf); + // Update the history table, stating that this user viewed this node. + node_tag_new($node->nid); + } + + return $block; +} + +function ctools_node_comments_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + $form['anchor'] = array( + '#type' => 'checkbox', + '#title' => t('HTML anchor'), + '#description' => t('If checked, an HTML anchor is added to allow linking within the same page. For example, http://example.com/node/2345#comment will take you to the comment area of the page.'), + // The anchor is enabled by default, but only on new panes. + '#default_value' => isset($conf['anchor']) ? $conf['anchor'] : 0, + '#weight' => 1, + ); + $form['mode'] = array( + '#type' => 'select', + '#title' => t('Mode'), + '#default_value' => $conf['mode'], + '#options' => _comment_get_modes(), + '#weight' => 2, + ); + $form['order'] = array( + '#type' => 'select', + '#title' => t('Sort'), + '#default_value' => $conf['order'], + '#options' => _comment_get_orders(), + '#weight' => 3, + ); + foreach (_comment_per_page() as $i) { + $options[$i] = t('!a comments per page', array('!a' => $i)); + } + $form['comments_per_page'] = array('#type' => 'select', + '#title' => t('Pager'), + '#default_value' => $conf['comments_per_page'], + '#options' => $options, + '#weight' => 4, + ); +} + +function ctools_node_comments_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +function ctools_node_comments_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" comments', array('@s' => $context->identifier)); +} + +/** + * This function is a somewhat stripped down version of comment_render + * that removes a bunch of cruft that we both don't need, and makes it + * difficult to modify this. + */ +function ctools_comment_render($node, $conf) { + $output = ''; + if (!user_access('access comments') || !$node->comment) { + return; + } + + $mode = $conf['mode']; + $order = $conf['order']; + $comments_per_page = $conf['comments_per_page']; + + // Multiple comment view + $query_count = 'SELECT COUNT(*) FROM {comments} c WHERE nid = %d'; + + if (db_column_exists('users', 'signature_format')) { + //We run drupal version > 6.13, users table has signature_format column + $query = 'SELECT c.cid AS cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.signature, u.signature_format, u.data, c.thread, c.status, parent_user.uid as parent_uid, parent_user.data as parent_data, parent_user.name as parent_name, parent_user.picture as parent_picture FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid LEFT OUTER JOIN {comments} parent ON c.pid = parent.cid LEFT OUTER JOIN {users} parent_user ON parent.uid = parent_user.uid WHERE c.nid = %d'; + } + else { + //We run outdated drupal version <= 6.13, users table doesn't have signature_format column + $query = 'SELECT c.cid AS cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.signature, u.data, c.thread, c.status, parent_user.uid as parent_uid, parent_user.data as parent_data, parent_user.name as parent_name, parent_user.picture as parent_picture FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid LEFT OUTER JOIN {comments} parent ON c.pid = parent.cid LEFT OUTER JOIN {users} parent_user ON parent.uid = parent_user.uid WHERE c.nid = %d'; + } + + $query_args = array($node->nid); + if (!user_access('administer comments')) { + $query .= ' AND c.status = %d'; + $query_count .= ' AND status = %d'; + $query_args[] = COMMENT_PUBLISHED; + } + + if ($order == COMMENT_ORDER_NEWEST_FIRST) { + if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) { + $query .= ' ORDER BY c.timestamp DESC'; + } + else { + $query .= ' ORDER BY c.thread DESC'; + } + } + else if ($order == COMMENT_ORDER_OLDEST_FIRST) { + if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) { + $query .= ' ORDER BY c.timestamp'; + } + else { + $query .= ' ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))'; + } + } + $query = db_rewrite_sql($query, 'c', 'cid'); + $query_count = db_rewrite_sql($query_count, 'c', 'cid'); + + // Start a form, for use with comment control. + $result = pager_query($query, $comments_per_page, 0, $query_count, $query_args); + + $divs = 0; + $last_depth = 0; + drupal_add_css(drupal_get_path('module', 'comment') .'/comment.css'); + while ($comment = db_fetch_object($result)) { + $comment = drupal_unpack($comment); + $comment->name = $comment->uid ? $comment->registered_name : $comment->name; + $comment->depth = count(explode('.', $comment->thread)) - 1; + + if ($mode == COMMENT_MODE_THREADED_COLLAPSED || $mode == COMMENT_MODE_THREADED_EXPANDED) { + if ($comment->depth > $last_depth) { + $divs++; + $output .= '<div class="indented">'; + $last_depth++; + } + else { + while ($comment->depth < $last_depth) { + $divs--; + $output .= '</div>'; + $last_depth--; + } + } + } + + if ($mode == COMMENT_MODE_FLAT_COLLAPSED) { + $output .= theme('comment_flat_collapsed', $comment, $node); + } + else if ($mode == COMMENT_MODE_FLAT_EXPANDED) { + $output .= theme('comment_flat_expanded', $comment, $node); + } + else if ($mode == COMMENT_MODE_THREADED_COLLAPSED) { + $output .= theme('comment_thread_collapsed', $comment, $node); + } + else if ($mode == COMMENT_MODE_THREADED_EXPANDED) { + $output .= theme('comment_thread_expanded', $comment, $node); + } + } + for ($i = 0; $i < $divs; $i++) { + $output .= '</div>'; + } + $output .= theme('pager', NULL, $comments_per_page, 0); + + if (!empty($conf['anchor'])) { + $output = '<div id="comments">' . $output . '</div>'; + } + return $output; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_content.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_content.inc new file mode 100644 index 0000000000000000000000000000000000000000..4a5b003acceafa427a5d7bf35955c8cdc41f4cfa --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_content.inc @@ -0,0 +1,220 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node content'), + 'icon' => 'icon_node.png', + 'description' => t('The content of the referenced node.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array( + 'links' => TRUE, + 'page' => TRUE, + 'no_extras' => TRUE, + 'override_title' => FALSE, + 'override_title_text' => '', + 'identifier' => '', + 'link' => TRUE, + 'leave_node_title' => FALSE, + 'build_mode' => 'teaser', + ), +); + +/** + * Render the node content. + */ +function ctools_node_content_content_type_render($subtype, $conf, $panel_args, $context) { + if (!empty($context) && empty($context->data)) { + return; + } + + $node = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'node'; + $block->delta = $node->nid; + + if (empty($node)) { + $block->delta = 'placeholder'; + $block->title = t('Node title.'); + $block->content = t('Node content goes here.'); + } + else { + if (!empty($conf['identifier'])) { + $node->panel_identifier = $conf['identifier']; + } + + $block->title = $node->title; + if (empty($conf['leave_node_title'])) { + $node->title = NULL; + } + $block->content = ctools_node_content_render_node($node, $conf); + } + + if (node_access('update', $node)) { + $block->admin_links['update'] = array( + 'title' => t('Edit node'), + 'alt' => t("Edit this node"), + 'href' => "node/$node->nid/edit", + ); + if (isset($_REQUEST['destination'])) { + $block->admin_links['update']['query'] = drupal_get_destination(); + } + } + + if (!empty($conf['link']) && $node) { + $block->title_link = "node/$node->nid"; + } + + return $block; +} + +function ctools_node_content_render_node($node, $conf) { + + // Handle existing configurations with the deprecated 'teaser' option. + if (isset($conf['teaser'])) { + $conf['build_mode'] = $conf['teaser'] ? 'teaser' : 'full'; + } + + // The build mode identifies the target for which the node is built. + if (!isset($node->build_mode)) { + $node->build_mode = ($conf['build_mode'] == 'teaser' || $conf['build_mode'] == 'full') ? NODE_BUILD_NORMAL : $conf['build_mode']; + } + + // Determine the $teaser variable. + $teaser = $conf['build_mode'] == 'teaser'; + + // Remove the delimiter (if any) that separates the teaser from the body. + $node->body = str_replace('<!--break-->', '', $node->body); + + // The 'view' hook can be implemented to overwrite the default function + // to display nodes. + if (node_hook($node, 'view')) { + $node = node_invoke($node, 'view', $teaser, $conf['page']); + } + else { + $node = node_prepare($node, $teaser); + } + + if (empty($conf['no_extras'])) { + // Allow modules to make their own additions to the node. + node_invoke_nodeapi($node, 'view', $teaser, $conf['page']); + } + + if ($conf['links']) { + $node->links = module_invoke_all('link', 'node', $node, $teaser); + drupal_alter('link', $node->links, $node); + } + + // Set the proper node part, then unset unused $node part so that a bad + // theme can not open a security hole. + $content = drupal_render($node->content); + if ($teaser) { + $node->teaser = $content; + unset($node->body); + } + else { + $node->body = $content; + unset($node->teaser); + } + + // Allow modules to modify the fully-built node. + node_invoke_nodeapi($node, 'alter', $teaser, $conf['page']); + + return theme('node', $node, $teaser, $conf['page']); +} + +/** + * Returns an edit form for the custom type. + */ +function ctools_node_content_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['leave_node_title'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($conf['leave_node_title']), + '#title' => t('Leave node title'), + '#description' => t('Advanced: if checked, do not touch the node title; this can cause the node title to appear twice unless your theme is aware of this.'), + ); + + $form['link'] = array( + '#title' => t('Link title to node'), + '#type' => 'checkbox', + '#default_value' => $conf['link'], + '#description' => t('Check here to make the title link to the node.'), + ); + $form['page'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['page'], + '#title' => t('Treat this as the primary node page'), + '#description' => t('This can affect title rendering and breadcrumbs from some node types.'), + ); + $form['links'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['links'], + '#title' => t('Include node links for "add comment", "read more" etc.'), + ); + + $form['no_extras'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['no_extras'], + '#title' => t('No extras'), + '#description' => t('Check here to disable additions that modules might make to the node, such as file attachments and CCK fields; this should just display the basic teaser or body.'), + ); + + $form['identifier'] = array( + '#type' => 'textfield', + '#default_value' => $conf['identifier'], + '#title' => t('Template identifier'), + '#description' => t('This identifier will be added as a template suggestion to display this node: node-panel-IDENTIFIER.tpl.php. Please see the Drupal theming guide for information about template suggestions.'), + ); + + // CCK holds the registry of available build modes, but can hardly + // push them as options for the build mode options, so we break the normal + // rule of not directly relying on non-core modules. + if ($modes = module_invoke('content', 'build_modes')) { + $build_mode_options = array(); + foreach ($modes as $key => $value) { + if (isset($value['views style']) && $value['views style']) { + $build_mode_options[$key] = $value['title']; + } + } + } + else { + $build_mode_options = array( + 'teaser' => t('Teaser'), + 'full' => t('Full node') + ); + } + + // Handle existing configurations with the deprecated 'teaser' option. + // Also remove the teaser key from the form_state. + if (isset($conf['teaser']) || !isset($conf['build_mode'])) { + unset($form_state['conf']['teaser']); + $conf['build_mode'] = $conf['teaser'] ? 'teaser' : 'full'; + } + $form['build_mode'] = array( + '#title' => t('Build mode'), + '#type' => 'select', + '#description' => t('Select a build mode for this node.'), + '#options' => $build_mode_options, + '#default_value' => $conf['build_mode'], + ); + + return $form; +} + +function ctools_node_content_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +function ctools_node_content_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" content', array('@s' => $context->identifier)); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_created.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_created.inc new file mode 100644 index 0000000000000000000000000000000000000000..b4beb2b4c5db4dd02a064811c29982748603ed13 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_created.inc @@ -0,0 +1,74 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node created date'), + 'icon' => 'icon_node.png', + 'description' => t('The date the referenced node was created.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array( + 'format' => 'small', + ), +); + +/** + * Render the custom content type. + */ +function ctools_node_created_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Get a shortcut to the node. + $node = $context->data; + + // Build the content type block. + $block = new stdClass(); + $block->module = 'node_created'; + $block->title = t('Created date'); + $block->content = format_date($node->created, $conf['format']); + $block->delta = $node->nid; + + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_node_created_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $time = time(); + $form['format'] = array( + '#title' => t('Date format'), + '#type' => 'select', + '#options' => array( + 'small' => format_date($time, 'small'), + 'medium' => format_date($time, 'medium'), + 'large' => format_date($time, 'large'), + ), + '#default_value' => $conf['format'], + ); +} + +/** + * Submit handler for the custom type settings form. + */ +function ctools_node_created_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a type. + */ +function ctools_node_created_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" created date', array('@s' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_links.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_links.inc new file mode 100644 index 0000000000000000000000000000000000000000..5fe81c35f99e6ee82cb22103f081dd37a15aaf48 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_links.inc @@ -0,0 +1,108 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node links'), + 'icon' => 'icon_node.png', + 'description' => t('Node links of the referenced node.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array( + 'override_title' => FALSE, + 'override_title_text' => '', + 'teaser' => TRUE, + 'identifier' => '', + 'link' => TRUE, + ), +); + +/** + * Output function for the 'node' content type. Outputs a node + * based on the module and delta supplied in the configuration. + */ +function ctools_node_links_content_type_render($subtype, $conf, $panel_args, $context) { + if (!empty($context) && empty($context->data)) { + return; + } + + $node = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'node'; + $block->delta = $node->nid; + + if (empty($node)) { + $block->delta = 'placeholder'; + $block->subject = t('Node title.'); + $block->content = t('Node links go here.'); + } + else { + if (!empty($conf['identifier'])) { + $node->panel_identifier = $conf['identifier']; + } + + $block->subject = $node->title; + + $block->content = ctools_node_links_render_links($node, $conf); + } + + if (!empty($conf['link']) && $node) { + $block->title_link = "node/$node->nid"; + } + return $block; +} + +function ctools_node_links_render_links($node, $conf) { + // The build mode identifies the target for which the node is built. + if (!isset($node->build_mode)) { + $node->build_mode = NODE_BUILD_NORMAL; + } + + $links = module_invoke_all('link', 'node', $node, $conf['teaser']); + drupal_alter('link', $links, $node); + return theme('links', $links); +} + +/** + * Returns an edit form for the custom type. + */ +function ctools_node_links_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['link'] = array( + '#title' => t('Link title to node'), + '#type' => 'checkbox', + '#default_value' => $conf['link'], + '#description' => t('Check here to make the title link to the node.'), + ); + $form['teaser'] = array( + '#title' => t('Teaser mode'), + '#type' => 'checkbox', + '#default_value' => $conf['teaser'], + '#description' => t('Check here to show links in teaser mode.'), + ); + + $form['identifier'] = array( + '#type' => 'textfield', + '#default_value' => $conf['identifier'], + '#title' => t('Identifier'), + '#description' => t('Whatever is placed here will appear in $node->panel_identifier to help theme node links displayed on the panel'), + ); + + return $form; +} + +function ctools_node_links_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +function ctools_node_links_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" links', array('@s' => $context->identifier)); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_terms.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_terms.inc new file mode 100644 index 0000000000000000000000000000000000000000..8fb59391acaa622b741fd02fcb11441aa61a34ab --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_terms.inc @@ -0,0 +1,186 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node terms'), + 'icon' => 'icon_node.png', + 'description' => t('Taxonomy terms of the referenced node.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array( + 'vid' => 0, + 'term_format' => 'term-links', + 'link' => TRUE, + 'term_delimiter' => ', ', + ), +); + +/** + * Render the node_terms content type. + */ +function ctools_node_terms_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Get a shortcut to the node. + $node = $context->data; + + if (empty($node->taxonomy)) { + return; + } + + $formatted_terms = ''; + if (empty($conf['vid']) && $conf['term_format'] == 'term-links') { + // They want all terms, formatted as term links, so we can just use + // taxonomy_link() directly. + $terms = taxonomy_link('taxonomy terms', $node); + $formatted_terms = theme('links', $terms); + } + else { + // They want something special and custom, we'll have to do this ourselves. + $terms = array(); + foreach ($context->data->taxonomy as $term) { + if (empty($conf['vid']) || $term->vid == $conf['vid']) { + if ($conf['term_format'] == 'term-links') { + // We have to do this manually since taxonomy_link() doesn't let you + // filter by vocabulary, so we just replicate it for the subset of + // terms matching the requested vid. + $terms['taxonomy_term_' . $term->tid] = array( + 'title' => $term->name, + 'href' => taxonomy_term_path($term), + 'attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description)), + ); + } + elseif (empty($conf['link'])) { + $terms[] = check_plain($term->name); + } + else { + $terms[] = l($term->name, taxonomy_term_path($term), array('attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description)))); + } + } + } + + switch ($conf['term_format']) { + case 'term-links': + // Since we didn't use taxonomy_link() directly, we need to invoke + // hook_link_alter() for this to work as sites will expect. + drupal_alter('link', $terms, $node); + $formatted_terms = theme('links', $terms); + break; + + case 'ul': + $formatted_terms = theme('item_list', $terms); + break; + + case 'inline-delimited': + $delimiter = isset($conf['term_delimiter']) ? $conf['term_delimiter'] : ', '; + $formatted_terms = implode($delimiter, $terms); + break; + + } + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'node_terms'; + $block->delta = $node->nid; + $block->title = $type->title_label; + $block->content = $formatted_terms; + + return $block; +} + +/** + * Returns an edit form for node terms display settings. + * + * The first question is if they want to display all terms or restrict it to a + * specific taxonomy vocabulary. + * + * Then, they're presented with a set of radios to find out how they want the + * terms formatted, which can be either be via theme('links'), a regular item + * list (ul), or inline with a delimiter. Depending on which radio they + * choose, some other settings might appear. If they're doing either the ul or + * inline, we ask if they want the terms to appear as links or not. If they + * want it inline, we ask what delimiter they want to use. + */ +function ctools_node_terms_content_type_edit_form(&$form, &$form_state) { + ctools_include('dependent'); + + $conf = $form_state['conf']; + + $options = array(); + $options[0] = t('- All vocabularies -'); + foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) { + $options[$vid] = $vocabulary->name; + } + $form['vid'] = array( + '#title' => t('Vocabulary'), + '#type' => 'select', + '#options' => $options, + '#default_value' => $conf['vid'], + '#description' => t('Optionally restrict the terms to a specific vocabulary, or allow terms from all vocabularies.'), + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + + $form['term_format'] = array( + '#type' => 'radios', + '#title' => t('Term formatting'), + '#options' => array( + 'term-links' => t("Taxonomy links (uses theme('links'))"), + 'ul' => t('Unordered list'), + 'inline-delimited' => t('Inline, delimited'), + ), + '#default_value' => $conf['term_format'], + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + + $form['link'] = array( + '#title' => t('Link to terms'), + '#type' => 'checkbox', + '#default_value' => $conf['link'], + '#description' => t('Check here to make the terms link to the term paths.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:term_format' => array('inline-delimited', 'ul')), + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + + $form['term_delimiter'] = array( + '#type' => 'textfield', + '#title' => t('Term delimiter'), + '#default_value' => $conf['term_delimiter'], + '#size' => 10, + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:term_format' => array('inline-delimited')), + ); +} + +/** + * Submit handler for the custom type settings form. + */ +function ctools_node_terms_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a type. + */ +function ctools_node_terms_content_type_admin_title($subtype, $conf, $context) { + $placeholders['@s'] = $context->identifier; + if (!empty($conf['vid'])) { + $vocabulary = taxonomy_vocabulary_load($conf['vid']); + $placeholders['@vocabulary'] = $vocabulary->name; + return t('"@s" terms from @vocabulary', $placeholders); + } + return t('"@s" terms', $placeholders); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_title.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_title.inc new file mode 100644 index 0000000000000000000000000000000000000000..e6a0197c0463c8b14cdae3b875542f8d375fb2a2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_title.inc @@ -0,0 +1,72 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node title'), + 'icon' => 'icon_node.png', + 'description' => t('The title of the referenced node.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array( + 'link' => TRUE, + ), +); + +/** + * Render the custom content type. + */ +function ctools_node_title_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Get a shortcut to the node. + $node = $context->data; + + // Load information about the node type. + $type = node_get_types('type', $node->type); + + // Build the content type block. + $block = new stdClass(); + $block->module = 'node_title'; + $block->title = $type->title_label; + $block->content = !empty($conf['link']) ? l($node->title, 'node/'. $node->nid) : check_plain($node->title); + $block->delta = $node->nid; + + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_node_title_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['link'] = array( + '#title' => t('Link to node'), + '#type' => 'checkbox', + '#default_value' => $conf['link'], + '#description' => t('Check here to make the title link to the node.'), + ); +} + +/** + * Submit handler for the custom type settings form. + */ +function ctools_node_title_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a type. + */ +function ctools_node_title_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" title', array('@s' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_type_desc.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_type_desc.inc new file mode 100644 index 0000000000000000000000000000000000000000..83e757f9fb47c045c8392bc574f9e286e3c942a9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_type_desc.inc @@ -0,0 +1,46 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node type description'), + 'icon' => 'icon_node.png', + 'description' => t('Node type description.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), +); + +/** + * Output function for the 'node' content type. Outputs a node + * based on the module and delta supplied in the configuration. + */ +function ctools_node_type_desc_content_type_render($subtype, $conf, $panel_args, $context) { + $node = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'node_type'; + + if ($node) { + $type = node_get_types('type', $node); + $block->title = $type->name; + $block->content = filter_xss_admin($type->description); + $block->delta = $node->type; + } + else { + $block->title = t('Node type description'); + $block->content = t('Node type description goes here.'); + $block->delta = 'unknown'; + } + + return $block; +} + +function ctools_node_type_desc_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" type description', array('@s' => $context->identifier)); +} + +function ctools_node_type_desc_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_updated.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_updated.inc new file mode 100644 index 0000000000000000000000000000000000000000..5c77d6a9e5bd2f628064237a9cefddc16355916d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_context/node_updated.inc @@ -0,0 +1,74 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node last updated date'), + 'icon' => 'icon_node.png', + 'description' => t('The date the referenced node was last updated.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'category' => t('Node'), + 'defaults' => array( + 'format' => 'small', + ), +); + +/** + * Render the custom content type. + */ +function ctools_node_updated_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Get a shortcut to the node. + $node = $context->data; + + // Build the content type block. + $block = new stdClass(); + $block->module = 'node_updated'; + $block->title = t('Last updated date'); + $block->content = format_date(!empty($node->changed) ? $node->changed : $node->created, $conf['format']); + $block->delta = $node->nid; + + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_node_updated_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $time = time(); + $form['format'] = array( + '#title' => t('Date format'), + '#type' => 'select', + '#options' => array( + 'small' => format_date($time, 'small'), + 'medium' => format_date($time, 'medium'), + 'large' => format_date($time, 'large'), + ), + '#default_value' => $conf['format'], + ); +} + +/** + * Submit handler for the custom type settings form. + */ +function ctools_node_updated_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a type. + */ +function ctools_node_updated_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" last updated date', array('@s' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/icon_node_form.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/icon_node_form.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/icon_node_form.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_attachments.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_attachments.inc new file mode 100644 index 0000000000000000000000000000000000000000..c6e7d29ad523f32c44a292741e0054d31967c4f0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_attachments.inc @@ -0,0 +1,44 @@ +<?php + +if (module_exists('upload')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form file attachments'), + 'description' => t('File attachments on the Node form.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), + ); +} + +function ctools_node_form_attachments_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = t('Attach files'); + $block->delta = 'url-path-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id']) && !empty($context->form['attachments']['#access'])) { + // remove the fieldset + unset($context->form['attachments']['#type']); + $block->content = drupal_render($context->form['attachments']); + } + } + else { + $block->content = t('Attach files.'); + } + return $block; +} + +function ctools_node_form_attachments_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form attach files', array('@s' => $context->identifier)); +} + +function ctools_node_form_attachments_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_author.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_author.inc new file mode 100644 index 0000000000000000000000000000000000000000..7efc53c76c11f792a70424c3e73fb23916387a6a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_author.inc @@ -0,0 +1,44 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form author information'), + 'description' => t('Author information on the Node form.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), +); + +function ctools_node_form_author_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = t('Authoring information'); + $block->delta = 'author-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id']) && !empty($context->form['author']['#access'])) { + // remove the fieldset + unset($context->form['author']['#type']); + $context->form['author']['name']['#size'] /= 2; + $context->form['author']['date']['#size'] /= 2; + $block->content = drupal_render($context->form['author']); + } + } + else { + $block->content = t('Authoring information.'); + } + return $block; +} + +function ctools_node_form_author_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form publishing options', array('@s' => $context->identifier)); +} + +function ctools_node_form_author_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_book.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_book.inc new file mode 100644 index 0000000000000000000000000000000000000000..b3c0b5d707f9c43be47e3f987f5cce4f274487a5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_book.inc @@ -0,0 +1,48 @@ +<?php + +if (module_exists('book')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form book options'), + 'description' => t('Book options for the node.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), + ); +} + +function ctools_node_form_book_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = t('Book options'); + $block->delta = 'book-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id'])) { + $block->content = ''; + if ($context->form['parent']['#type'] != 'value') { + $block->content .= drupal_render($context->form['parent']); + } + if ($context->form['weight']['#type'] != 'value') { + $block->content .= drupal_render($context->form['weight']); + } + } + } + else { + $block->content = t('Book options.'); + } + return $block; +} + +function ctools_node_form_book_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form book options', array('@s' => $context->identifier)); +} + +function ctools_node_form_book_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_buttons.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_buttons.inc new file mode 100644 index 0000000000000000000000000000000000000000..c980f342d10174237012f81d1c63ce19cb916508 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_buttons.inc @@ -0,0 +1,41 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form submit buttons'), + 'description' => t('Submit buttons for the node form.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), +); + +function ctools_node_form_buttons_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = ''; + $block->delta = 'buttons'; + + if (isset($context->form)) { + $block->content = drupal_render($context->form['buttons']); + $block->content .= drupal_render($context->form['form_token']); + $block->content .= drupal_render($context->form['form_build_id']); + $block->content .= drupal_render($context->form['form_id']); + } + else { + $block->content = t('Node form buttons.'); + } + return $block; +} + +function ctools_node_form_buttons_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form submit buttons', array('@s' => $context->identifier)); +} + +function ctools_node_form_buttons_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_comment.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_comment.inc new file mode 100644 index 0000000000000000000000000000000000000000..c182b074efd6e489afab25915d82888aa183a092 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_comment.inc @@ -0,0 +1,44 @@ +<?php + +if (module_exists('comment')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form comment settings'), + 'description' => t('Comment settings on the Node form.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), + ); +} + +function ctools_node_form_comment_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = t('Comment options'); + $block->delta = 'comment-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id']) && !empty($context->form['comment_settings']['#access'])) { + // remove the fieldset + unset($context->form['comment_settings']['#type']); + $block->content = drupal_render($context->form['comment_settings']); + } + } + else { + $block->content = t('Comment options.'); + } + return $block; +} + +function ctools_node_form_comment_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form comment settings', array('@s' => $context->identifier)); +} + +function ctools_node_form_comment_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_input_format.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_input_format.inc new file mode 100644 index 0000000000000000000000000000000000000000..9b23b4e8550a0d882d5a03e4503cf6ff2ffa2dcc --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_input_format.inc @@ -0,0 +1,42 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form input format'), + 'description' => t('Input format for the body field on a node.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), +); + +function ctools_node_form_input_format_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = t('Input format'); + $block->delta = 'format-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id']) && !empty($context->form['body_filter']['format'])) { + // remove the fieldset + unset($context->form['body_filter']['format']['#type']); + $block->content = drupal_render($context->form['body_filter']['format']); + } + } + else { + $block->content = t('Input format.'); + } + return $block; +} + +function ctools_node_form_input_format_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form input format', array('@s' => $context->identifier)); +} + +function ctools_node_form_input_format_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_log.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_log.inc new file mode 100644 index 0000000000000000000000000000000000000000..c7f5f5b50173ebe932e00b95e39377d3143475cd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_log.inc @@ -0,0 +1,31 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form revision log message'), + 'description' => t('Revision log message for the node.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), +); + +function ctools_node_form_log_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + // @todo -- this was never implemented!? + + return $block; +} + +function ctools_node_form_log_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form revision log', array('@s' => $context->identifier)); +} + +function ctools_node_form_log_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_menu.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..57ff37359f6cb6e2f9866ce68cf15e776cf921b8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_menu.inc @@ -0,0 +1,45 @@ +<?php + +if (module_exists('menu')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form menu settings'), + 'description' => t('Menu settings on the Node form.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), + ); +} + +function ctools_node_form_menu_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = t('Menu options'); + $block->delta = 'menu-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id']) && !empty($context->form['menu']['#access'])) { + // remove the fieldset + unset($context->form['menu']['#type']); + $context->form['menu']['link_title']['#size'] /= 2; + $block->content = drupal_render($context->form['menu']); + } + } + else { + $block->content = t('Menu options.'); + } + return $block; +} + +function ctools_node_form_menu_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form menu settings', array('@s' => $context->identifier)); +} + +function ctools_node_form_menu_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_path.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_path.inc new file mode 100644 index 0000000000000000000000000000000000000000..f245698895ba4609d73ddcf56f8841b4115bb694 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_path.inc @@ -0,0 +1,45 @@ +<?php + +if (module_exists('path')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form url path settings'), + 'description' => t('Publishing options on the Node form.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), + ); +} + +function ctools_node_form_path_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = t('URL path options'); + $block->delta = 'url-path-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id']) && !empty($context->form['path']['#access'])) { + // remove the fieldset + unset($context->form['path']['#type']); + $context->form['path']['path']['#size'] /= 2; + $block->content = drupal_render($context->form['path']); + } + } + else { + $block->content = t('URL Path options.'); + } + return $block; +} + +function ctools_node_form_path_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form path options', array('@s' => $context->identifier)); +} + +function ctools_node_form_path_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_publishing.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_publishing.inc new file mode 100644 index 0000000000000000000000000000000000000000..4ce6833b149325290ae57618431f161668bc276b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_publishing.inc @@ -0,0 +1,48 @@ +<?php + +/** + * @file + * Publishing options form for the node. This contains the basic settings + * like published, moderated, node revision, etc. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Node form publishing options'), + 'icon' => 'icon_node_form.png', + 'description' => t('Publishing options on the Node form.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), +); + +function ctools_node_form_publishing_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + + $block->title = t('Publishing options'); + $block->module = t('node_form'); + $block->delta = 'publishing-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id']) && $context->form['options']['#type'] == 'fieldset') { + // remove the fieldset + unset($context->form['options']['#type']); + $block->content = drupal_render($context->form['options']); + } + } + else { + $block->content = t('Publishing options.'); + } + return $block; +} + +function ctools_node_form_publishing_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form author information', array('@s' => $context->identifier)); +} + +function ctools_node_form_publishing_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_taxonomy.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_taxonomy.inc new file mode 100644 index 0000000000000000000000000000000000000000..5b3b8bc80f299c6d79634620ca7091f695cd4a0f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/node_form/node_form_taxonomy.inc @@ -0,0 +1,44 @@ +<?php + +if (module_exists('taxonomy')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'icon' => 'icon_node_form.png', + 'title' => t('Node form categories'), + 'description' => t('Taxonomy categories for the node.'), + 'required context' => new ctools_context_required(t('Form'), 'node_form'), + 'category' => t('Form'), + ); +} + +function ctools_node_form_taxonomy_content_type_render($subtype, $conf, $panel_args, &$context) { + $block = new stdClass(); + $block->module = t('node_form'); + + $block->title = t('Categories'); + $block->delta = 'url-path-options'; + + if (isset($context->form)) { + if (!empty($context->form['form_id']) && !empty($context->form['taxonomy'])) { + // remove the fieldset + unset($context->form['taxonomy']['#type']); + $block->content = drupal_render($context->form['taxonomy']); + } + } + else { + $block->content = t('Categories.'); + } + return $block; +} + +function ctools_node_form_taxonomy_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" node form select taxonomy', array('@s' => $context->identifier)); +} + +function ctools_node_form_taxonomy_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_breadcrumb.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_breadcrumb.inc new file mode 100644 index 0000000000000000000000000000000000000000..ebec681463ebb4025bd12d65b8d0d49ca5ca6026 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_breadcrumb.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Plugin to handle the 'page_breadcrumb' content type which allows the + * breadcrumb trail of the current page to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Breadcrumb'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the breadcrumb trail as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_breadcrumb' content type. + * + * Outputs the breadcrumb for the current page. + */ +function ctools_page_breadcrumb_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = theme('breadcrumb', drupal_get_breadcrumb()); + + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_feed_icons.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_feed_icons.inc new file mode 100644 index 0000000000000000000000000000000000000000..0dba317d856c87e7df299679df8e7decfd47aac4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_feed_icons.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Plugin to handle the 'page_feed_icons' content type which allows the + * feed_icons statement of the site to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Feed icons'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the site feed_icons statement as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_feed_icons' content type. + * + * Outputs the feed_icons statement for the site. + */ +function ctools_page_feed_icons_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = drupal_get_feeds(); + + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_footer_message.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_footer_message.inc new file mode 100644 index 0000000000000000000000000000000000000000..369e744e6a54fb0e31d6d04df8ea0d50bc1a6546 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_footer_message.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Plugin to handle the 'page' content type which allows the standard page + * template variables to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Page footer message'), + 'icon' => 'icon_page.png', + 'description' => t('Add the page footer message as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_footer_message' content type. + * + * Outputs the page footer message of the current page. + */ +function ctools_page_footer_message_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = filter_xss_admin(variable_get('site_footer', FALSE)); + + return $block; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_help.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_help.inc new file mode 100644 index 0000000000000000000000000000000000000000..da1abe69f5fb5e8967cf49123f2c9067311b1252 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_help.inc @@ -0,0 +1,33 @@ +<?php + +/** + * @file + * Plugin to handle the 'page_help' content type which allows the + * help text of the current page to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Help'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the help text of the current page as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_help' content type. + * + * Outputs the breadcrumb for the current page. + */ +function ctools_page_help_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = theme('help'); + + return $block; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_logo.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_logo.inc new file mode 100644 index 0000000000000000000000000000000000000000..c00ca5e888ba6869d8e17c6620a53a41ed820270 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_logo.inc @@ -0,0 +1,37 @@ +<?php + +/** + * @file + * Plugin to handle the 'page_logo' content type which allows the + * logo of the site to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Site logo'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the logo trail as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_logo' content type. + * + * Outputs the logo for the current page. + */ +function ctools_page_logo_content_type_render($subtype, $conf, $panel_args) { + $logo = theme_get_setting('logo'); + $block = new stdClass(); + + if (!empty($logo)) { + $image = '<img src="' . $logo . '" alt="' . t('Home') . '" />'; + $block->content = l($image, '', array('html' => TRUE, 'attributes' => array('rel' => 'home', 'id' => 'logo', 'title' => t('Home')))); + } + + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_messages.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_messages.inc new file mode 100644 index 0000000000000000000000000000000000000000..e2fe37b3574d67dc0e9d6adfe9d238ae5b0357a6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_messages.inc @@ -0,0 +1,33 @@ +<?php + +/** + * @file + * Plugin to handle the 'page_messages' content type which allows the + * status messages of the current page to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Status messages'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the status messages of the current page as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_messages' content type. + * + * Outputs the breadcrumb for the current page. + */ +function ctools_page_messages_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = theme('status_messages'); + + return $block; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_mission.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_mission.inc new file mode 100644 index 0000000000000000000000000000000000000000..5fb5002f8ba155aa772021c36d98a8d4ff91d8e3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_mission.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Plugin to handle the 'page_mission' content type which allows the + * mission statement of the site to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Mission'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the site mission statement as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_mission' content type. + * + * Outputs the mission statement for the site. + */ +function ctools_page_mission_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = filter_xss_admin(theme_get_setting('mission')); + + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_primary_links.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_primary_links.inc new file mode 100644 index 0000000000000000000000000000000000000000..1754f341a3edf92efa6530a689f419fd0596963f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_primary_links.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Plugin to handle the 'page' content type which allows the standard page + * template variables to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Primary navigation links'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the primary_links (local tasks) as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_primary_links' content type. + * + * Outputs the primary_links (local tasks) of the current page. + */ +function ctools_page_primary_links_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = theme('links', menu_primary_links(), array('class' => 'links primary-links')); + + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_secondary_links.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_secondary_links.inc new file mode 100644 index 0000000000000000000000000000000000000000..c0dd6382215a557208d6fd3f13f9f60398bf6c1b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_secondary_links.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Plugin to handle the 'page' content type which allows the standard page + * template variables to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Secondary navigation links'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the secondary_links (local tasks) as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_secondary_links' content type. + * + * Outputs the secondary_links (local tasks) of the current page. + */ +function ctools_page_secondary_links_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = theme('links', menu_secondary_links(), array('class' => 'links secondary-links')); + + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_site_name.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_site_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..99501f2c1f9ef46799a55870cc7aca756d41aec3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_site_name.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Plugin to handle the 'page_site_name' content type which allows the + * site_name of the site to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Site name'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('The name of the site.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_site_name' content type. + * + * Outputs the site_name for the current page. + */ +function ctools_page_site_name_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = filter_xss_admin(variable_get('site_name', 'Drupal')); + + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_slogan.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_slogan.inc new file mode 100644 index 0000000000000000000000000000000000000000..58f913f6017ac8d52b5c191b75af77a748b24f6f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_slogan.inc @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Plugin to handle the 'page_slogan' content type which allows the + * slogan of the site to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Site slogan'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the slogan trail as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, +); + +/** + * Output function for the 'page_slogan' content type. + * + * Outputs the slogan for the current page. + */ +function ctools_page_slogan_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = (theme_get_setting('toggle_slogan') ? filter_xss_admin(variable_get('site_slogan', '')) : ''); + + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_tabs.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_tabs.inc new file mode 100644 index 0000000000000000000000000000000000000000..eed9663c5af708a6e0a306ee322233f4de2669ff --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_tabs.inc @@ -0,0 +1,69 @@ +<?php + +/** + * @file + * Plugin to handle the 'page' content type which allows the standard page + * template variables to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Tabs'), + 'single' => TRUE, + 'icon' => 'icon_page.png', + 'description' => t('Add the tabs (local tasks) as content.'), + 'category' => t('Page elements'), + 'render last' => TRUE, + 'defaults' => array( + 'type' => 'both', + 'id' => 'tabs', + ), +); + +/** + * Output function for the 'page_tabs' content type. + * + * Outputs the tabs (local tasks) of the current page. + */ +function ctools_page_tabs_content_type_render($subtype, $conf, $panel_args) { + $block = new stdClass(); + $block->content = theme('menu_local_tasks'); + + return $block; +} + + +function ctools_page_tabs_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['type'] = array( + '#title' => t('Tabs type'), + '#type' => 'select', + '#options' => array( + 'both' => t('Primary and secondary'), + 'primary' => t('Primary'), + 'secondary' => t('Secondary'), + ), + '#default_value' => $conf['type'], + ); + + $form['id'] = array( + '#title' => t('CSS id to use'), + '#type' => 'textfield', + '#default_value' => $conf['id'], + ); +} + +/** + * The submit form stores the data in $conf. + */ +function ctools_page_tabs_content_type_edit_form_submit(&$form, &$form_state) { + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + if (isset($form_state['values'][$key])) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_title.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_title.inc new file mode 100644 index 0000000000000000000000000000000000000000..bba6209dd20900a21d226fdeb467d276be1c17a6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/page/page_title.inc @@ -0,0 +1,117 @@ +<?php + +/** + * @file + * Plugin to handle the 'page' content type which allows the standard page + * template variables to be embedded into a panel. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Page title'), + 'icon' => 'icon_page.png', + 'description' => t('Add the page title as content.'), + 'category' => t('Page elements'), + 'defaults' => array( + 'markup' => 'h1', + 'class' => '', + 'id' => '', + ), +); + +/** + * Output function for the 'page_title' content type. + * + * Outputs the page title of the current page. + */ +function ctools_page_title_content_type_render($subtype, $conf, $panel_args) { + // TODO: This should have a setting or something for the markup. + if (empty($conf['markup'])) { + $conf['markup'] = 'h1'; + } + + if (empty($conf['class'])) { + $conf['class'] = ''; + } + + if (empty($conf['id'])) { + $conf['id'] = ''; + } + + $token = ctools_set_callback_token('title', array('ctools_page_title_content_type_token', $conf['markup'], $conf['id'], $conf['class'])); + + $block = new stdClass(); + if ($token) { + $block->content = $token; + } + + return $block; +} + +function ctools_page_title_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['markup'] = array( + '#title' => t('Title tag'), + '#type' => 'select', + '#options' => array( + 'none' => t('- No tag -'), + 'h1' => t('h1'), + 'h2' => t('h2'), + 'h3' => t('h3'), + 'h4' => t('h4'), + 'h5' => t('h5'), + 'h6' => t('h6'), + 'div' => t('div'), + ), + '#default_value' => empty($conf['markup']) ? 'h1' : $conf['markup'], + ); + + $form['id'] = array( + '#title' => t('CSS id to use'), + '#type' => 'textfield', + '#default_value' => empty($conf['id']) ? '' : $conf['id'], + ); + + $form['class'] = array( + '#title' => t('CSS class to use'), + '#type' => 'textfield', + '#default_value' => empty($conf['class']) ? '' : $conf['class'], + ); +} + +/** + * The submit form stores the data in $conf. + */ +function ctools_page_title_content_type_edit_form_submit(&$form, &$form_state) { + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + if (isset($form_state['values'][$key])) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } + } +} + +/** + * Variable token callback to properly render the page title, with markup. + */ +function ctools_page_title_content_type_token(&$variables, $tag, $id, $class) { + if ($tag == 'none') { + return drupal_get_title(); + } + + $output = '<' . $tag; + if ($id) { + $output .= ' id="' . $id . '"'; + } + + if ($class) { + $output .= ' class="' . $class . '"'; + } + + $output .= '>' . drupal_get_title() . '</' . $tag . '>' . "\n"; + return $output; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/icon_search.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/icon_search.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad1deb65c4a1cada8cdedb7619f3ed5e8ff0587 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/icon_search.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/search_form.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/search_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..a1422568dd15c32e5d705049cc3756d36759a249 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/search_form.inc @@ -0,0 +1,168 @@ +<?php + +if (module_exists('search')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Advanced search form'), + 'icon' => 'icon_search.png', + 'description' => t('A search form with advanced options.'), + 'required context' => new ctools_context_optional(t('Keywords'), 'string'), + 'category' => t('Widgets'), + 'defaults' => array( + 'type' => 'node', + 'form' => 'advanced', + 'path_type' => 'default', + 'path' => '', + 'override_prompt' => FALSE, + 'prompt' => '', + ), + ); +} + +/** + * Render the custom content type. + */ +function ctools_search_form_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + $keys = ''; + } + else { + $keys = $context->data; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'search'; + $block->delta = 'form'; + $block->title = ''; + + switch ($conf['path_type']) { + default: + case 'default': + $path = 'search/' . $conf['type']; + break; + case 'same': + $path = $_GET['q']; + $path = str_replace($keys, '', $path); + break; + case 'custom': + $path = $conf['path']; + break; + } + + $prompt = $conf['override_prompt'] ? $conf['prompt'] : NULL; + + $form_state = array( + 'no_redirect' => TRUE, + 'args' => array(url($path), $keys, $conf['type'], $prompt), + ); + + ctools_include('form'); + module_load_include('inc', 'search', 'search.pages'); + + $form_id = $conf['form'] == 'simple' ? 'ctools_search_form' : 'search_form'; + $block->content = ctools_build_form($form_id, $form_state); + + // We do the redirect manually because the built in search form is stupid + // and won't redirect even though action is a valid argument for it. + if (empty($block->content)) { + drupal_goto($path . '/' . $form_state['values']['processed_keys']); + } + + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_search_form_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $types = array(); + foreach (module_implements('search') as $name) { + $types[$name] = module_invoke($name, 'search', 'name', TRUE); + } + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Search type'), + '#options' => $types, + '#default_value' => $conf['type'], + ); + + $form['form'] = array( + '#type' => 'select', + '#title' => t('Search form'), + '#options' => array( + 'simple' => t('Simple'), + 'advanced' => t('Advanced'), + ), + '#default_value' => $conf['form'], + '#description' => t('The advanced form may have additional options based upon the search type. For example the advanced content (node) search form will allow searching by node type and taxonomy term.'), + ); + + $form['path_type'] = array( + '#prefix' => '<div class="container-inline">', + '#type' => 'select', + '#title' => t('Path'), + '#options' => array( + 'default' => t('Default'), + 'same' => t('Same page'), + 'custom' => t('Custom'), + ), + '#default_value' => $conf['path_type'], + ); + + $form['path'] = array( + '#type' => 'textfield', + '#default_value' => $conf['path'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-path-type' => array('custom')), + '#suffix' => '</div>', + ); + + $form['override_prompt'] = array( + '#prefix' => '<div class="container-inline">', + '#type' => 'checkbox', + '#default_value' => $conf['override_prompt'], + '#title' => t('Override default prompt'), + ); + + $form['prompt'] = array( + '#type' => 'textfield', + '#default_value' => $conf['prompt'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-override-prompt' => array(1)), + '#suffix' => '</div>', + ); +} + +/** + * Submit handler for search form. + */ +function ctools_search_form_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a type. + */ +function ctools_search_form_content_type_admin_title($subtype, $conf, $context) { + $type = module_invoke($conf['type'], 'search', 'name', TRUE); + return t('@type search form', array('@type' => $type)); +} + +/** + * Form alter the submit/validate onto our customized search form. + */ +function ctools_form_ctools_search_form_alter(&$form, &$form_state) { + $form['#validate'] = array('search_form_validate'); + $form['#submit'] = array('search_form_submit'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/search_result.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/search_result.inc new file mode 100644 index 0000000000000000000000000000000000000000..c96dff90df858429ef802970b8a5e5258278088d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/search/search_result.inc @@ -0,0 +1,202 @@ +<?php + +if (module_exists('search')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Search results'), + 'icon' => 'icon_search.png', + 'description' => t('The results of a search using keywords.'), + 'required context' => new ctools_context_required(t('Keywords'), 'string'), + 'category' => t('Widgets'), + 'defaults' => array( + 'type' => 'node', + 'log' => TRUE, + 'override_empty' => FALSE, + 'empty_title' => '', + 'empty' => '', + 'empty_format' => FILTER_FORMAT_DEFAULT, + 'override_no_key' => FALSE, + 'no_key_title' => '', + 'no_key' => '', + 'no_key_format' => FILTER_FORMAT_DEFAULT, + ), + ); +} + +/** + * Render the custom content type. + */ +function ctools_search_result_content_type_render($subtype, $conf, $panel_args, $context) { + // Display nothing at all if no keywords were entered. + if (empty($context) || empty($context->data)) { + if (!empty($conf['override_no_key'])) { + $block->title = $conf['no_key_title']; + $block->content = check_markup($conf['no_key'], $conf['no_key_format'], FALSE); + return $block; + } + return; + } + + $keys = $context->data; + + // Build the content type block. + $block = new stdClass(); + $block->module = 'search'; + $block->delta = 'result'; + + $results = ''; + + // Need settings for: + // $no result override + + if (!empty($conf['log'])) { + // Log the search keys: + watchdog('search', '%keys (@type).', array('%keys' => $keys, '@type' => module_invoke($conf['type'], 'search', 'name')), WATCHDOG_NOTICE, l(t('results'), $_GET['q'])); + } + + // Collect the search results: + $results = search_data($keys, $conf['type']); + + if ($results) { + $block->title = t('Search results'); + $block->content = $results; + } + else { + if (empty($conf['override_empty'])) { + $block->title = t('Your search yielded no results'); + $block->content = search_help('search#noresults', drupal_help_arg()); + } + else { + $block->title = $conf['empty_title']; + $block->content = check_markup($conf['empty'], $conf['empty_format'], FALSE); + } + } + + return $block; +} + +/** + * Returns an edit form for custom type settings. + */ +function ctools_search_result_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + // Add js for collapsible fieldsets manually + drupal_add_js('misc/collapse.js'); + + $types = array(); + foreach (module_implements('search') as $name) { + $types[$name] = module_invoke($name, 'search', 'name', TRUE); + } + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Search type'), + '#options' => $types, + '#default_value' => $conf['type'], + ); + + $form['log'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['log'], + '#title' => t('Record a watchdog log entry when searches are made'), + ); + + $form['override_empty'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['override_empty'], + '#title' => t('Override "no result" text'), + ); + + $form['empty_field']['empty_title'] = array( + '#title' => t('Title'), + '#type' => 'textfield', + '#default_value' => $conf['empty_title'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-override-empty' => array(1)), + ); + + $form['empty_field']['empty'] = array( + '#title' => t('No result text'), + '#type' => 'textarea', + '#default_value' => $conf['empty'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-override-empty' => array(1)), + ); + + $form['empty_field']['format_prefix'] = array( + '#type' => 'hidden', + '#id' => 'edit-empty-format', + '#prefix' => '<div><fieldset id="edit-empty-format" class="collapsed collapsible"><legend>' . t('Input format') . '</legend>', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-override-empty' => array(1)), + ); + // Yes, lots of gymnastics to make this fieldset work with dependencies. + $form['empty_field']['empty_format'] = filter_form($conf['empty_format'], NULL, array('empty_format')); + unset($form['empty_field']['empty_format']['#type']); + + $form['empty_field']['format_suffix'] = array( + '#value' => '</fieldset></div>', + ); + + + $form['override_no_key'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['override_no_key'], + '#title' => t('Display text if no search keywords were submitted'), + ); + + $form['no_key_field']['no_key_title'] = array( + '#title' => t('Title'), + '#type' => 'textfield', + '#default_value' => $conf['no_key_title'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-override-no-key' => array(1)), + ); + + $form['no_key_field']['no_key'] = array( + '#title' => t('No keywords text'), + '#type' => 'textarea', + '#default_value' => $conf['no_key'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-override-no-key' => array(1)), + ); + + $form['no_key_field']['format_prefix'] = array( + '#type' => 'hidden', + '#id' => 'edit-no-key-format', + '#prefix' => '<div><fieldset id="edit-no-key-format" class="collapsed collapsible"><legend>' . t('Input format') . '</legend>', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-override-no-key' => array(1)), + ); + // Yes, lots of gymnastics to make this fieldset work with dependencies. + $form['no_key_field']['no_key_format'] = filter_form($conf['no_key_format'], NULL, array('no_key_format')); + unset($form['no_key_field']['no_key_format']['#type']); + + $form['no_key_field']['format_suffix'] = array( + '#value' => '</fieldset></div>', + ); + +} + +/** + * Submit handler for search form. + */ +function ctools_search_result_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a type. + */ +function ctools_search_result_content_type_admin_title($subtype, $conf, $context) { + $type = module_invoke($conf['type'], 'search', 'name', TRUE); + return t('@type search result', array('@type' => $type)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/icon_term.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/icon_term.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/icon_term.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/term_description.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/term_description.inc new file mode 100644 index 0000000000000000000000000000000000000000..91f8804bb5c89d293298442095b0b526302208cb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/term_description.inc @@ -0,0 +1,49 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('Term description'), + 'icon' => 'icon_term.png', + 'description' => t('Term description.'), + 'required context' => new ctools_context_required(t('Term'), 'term'), + 'category' => t('Taxonomy term'), +); + +function ctools_term_description_content_type_render($subtype, $conf, $panel_args, $context) { + $term = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'node_type'; + + $block->title = $term->name; + if ($term) { + $block->content = _filter_autop(filter_xss_admin($term->description)); + $block->delta = $term->tid; + + if (user_access('administer taxonomy')) { + $block->admin_links['update'] = array( + 'title' => t('Edit term'), + 'alt' => t("Edit this term"), + 'href' => "admin/content/taxonomy/edit/term/$term->tid", + 'query' => drupal_get_destination(), + ); + } + } + else { + $block->content = t('Term description goes here.'); + $block->delta = 'unknown'; + } + + return $block; +} + +function ctools_term_description_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" term description', array('@s' => $context->identifier)); +} + +function ctools_term_description_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/term_list.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/term_list.inc new file mode 100644 index 0000000000000000000000000000000000000000..901644c5bc1e93bbee499d3c281115fb04ac36c4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/term_context/term_list.inc @@ -0,0 +1,116 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('List of related terms'), + 'icon' => 'icon_term.png', + 'description' => t('Terms related to an existing term; may be child, siblings or top level.'), + 'required context' => new ctools_context_required(t('Term'), 'term'), + 'category' => t('Taxonomy term'), + 'defaults' => array('title' => '', 'type' => 'child', 'list_type' => 'ul'), +); + +function ctools_term_list_content_type_render($subtype, $conf, $panel_args, $context) { + $term = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'term-list'; + + $options = ctools_admin_term_list_options(); + if ($term) { + $block->subject = $options[$conf['type']]; + $block->delta = $conf['type']; + switch ($conf['type']) { + case 'related': + $terms = taxonomy_get_related($term->tid); + break; + + case 'child': + default: + $terms = taxonomy_get_children($term->tid); + break; + + case 'top': + $terms = taxonomy_get_children(0, $term->vid); + break; + + case 'sibling': + $parent = db_result(db_query("SELECT parent FROM {term_hierarchy} WHERE tid = %d", $term->tid)); + $terms = taxonomy_get_children($parent, $term->vid); + // Remove the term that started this. + unset($terms[$term->tid]); + break; + + case 'synonyms': + $terms = taxonomy_get_synonyms($term->tid); + break; + } + if ($terms) { + foreach ($terms as $related) { + if (is_object($related)) { + $items[] = l($related->name, taxonomy_term_path($related), array('rel' => 'tag', 'title' => strip_tags($related->description))); + } + else { + $items[] = check_plain($related); + } + } + + $block->content = theme('item_list', $items, NULL, $conf['list_type']); + } + } + else { + $block->content = t('Term description goes here.'); + $block->delta = 'unknown'; + } + + return $block; +} + +function ctools_admin_term_list_options() { + return array( + 'child' => t('Child terms'), + 'related' => t('Related terms'), + 'sibling' => t('Sibling terms'), + 'top' => t('Top level terms'), + 'synonyms' => t('Term synonyms'), + ); +} + +/** + * Returns an edit form for the custom type. + */ +function ctools_term_list_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['type'] = array( + '#type' => 'radios', + '#title' => t('Which terms'), + '#options' => ctools_admin_term_list_options(), + '#default_value' => $conf['type'], + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + + $form['list_type'] = array( + '#type' => 'select', + '#title' => t('List type'), + '#options' => array('ul' => t('Unordered'), 'ol' => t('Ordered')), + '#default_value' => $conf['list_type'], + ); +} + +function ctools_term_list_content_type_admin_title($subtype, $conf, $context) { + $options = ctools_admin_term_list_options(); + return t('"@s" @type', array('@s' => $context->identifier, '@type' => drupal_strtolower($options[$conf['type']]))); +} + +function ctools_term_list_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/icon_user.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/icon_user.png new file mode 100644 index 0000000000000000000000000000000000000000..ab248f3f1bb62536bbf23296a949bfe05cd56bc7 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/icon_user.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/profile_fields.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/profile_fields.inc new file mode 100644 index 0000000000000000000000000000000000000000..459ee706e04e0bf19b7f97964a219201c07f062e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/profile_fields.inc @@ -0,0 +1,128 @@ +<?php + +if (module_exists('profile') && !is_null(profile_categories())) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Profile category'), + 'icon' => 'icon_user.png', + 'description' => t('Contents of a single profile category.'), + 'required context' => new ctools_context_required(t('User'), 'user'), + 'category' => t('User'), + 'defaults' => array('category' => '', 'empty' => ''), + 'hook theme' => 'ctools_profile_fields_content_type_theme', + ); +} + +/** + * 'Render' callback for the 'profile fields' content type. + */ +function ctools_profile_fields_content_type_render($subtype, $conf, $panel_args, $context) { + $account = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'profile fields'; + + if ($account) { + // Get the category from the options + $category = str_replace("_", " ", $conf['category']); + + // Set the subject to the name of the category + $block->subject = $category; + + // Put all the fields in the category into an array + profile_view_profile($account); + + if (is_array($account->content[$category])) { + foreach ($account->content[$category] as $field) { + if (is_array($field['#attributes'])) { + $vars[$field['#attributes']['class']]['title'] = $field['#title']; + $vars[$field['#attributes']['class']]['value'] = $field['#value']; + } + } + } + + if (count($vars) == 0) { + // Output the given empty text + $output = $conf['empty']; + } + else { + // Call the theme function with the field vars + $output = theme('profile_fields_pane', $category, $vars); + } + + $block->content = $output; + $block->delta = $account->uid; + } + else { + $block->subject = $conf['category']; + $block->content = t('Profile content goes here.'); + $block->delta = 'unknown'; + } + + return $block; +} +/** + * Helper function : build the list of categories for the 'edit' form. + */ +function _ctools_profile_fields_options() { + $cat_list = array(); + + $categories = profile_categories(); + foreach ($categories as $key => $value) { + $cat_list[str_replace(" ", "_", $value['name'])] = $value['title']; + } + + return $cat_list; +} + +/** + * 'Edit' callback for the 'profile fields' content type. + */ +function ctools_profile_fields_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + $form['category'] = array( + '#type' => 'radios', + '#title' => t('Which category'), + '#options' => _ctools_profile_fields_options(), + '#default_value' => $conf['category'], + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + + $form['empty'] = array( + '#type' => 'textarea', + '#title' => 'Empty text', + '#description' => t('Text to display if category has no data. Note that title will not display unless overridden.'), + '#rows' => 5, + '#default_value' => $conf['empty'], + '#prefix' => '<div class="clear-block no-float">', + '#suffix' => '</div>', + ); + + return $form; +} + +function ctools_profile_fields_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * 'Title' callback for the 'profile fields' content type. + */ +function ctools_profile_fields_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" profile fields', array('@s' => $conf['category'])); +} + +function ctools_profile_fields_content_type_theme(&$theme, $plugin) { + $theme['profile_fields_pane'] = array( + 'arguments' => array('category' => NULL, 'vars' => NULL), + 'path' => $plugin['path'], + 'template' => 'profile_fields_pane', + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/profile_fields_pane.tpl.php b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/profile_fields_pane.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..373681213aacea3506e5ca2ab2ebdf767d1e6b54 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/profile_fields_pane.tpl.php @@ -0,0 +1,16 @@ +<?php +/** + * @file + * Display profile fields. + * + * @todo Need definition of what variables are available here. + */ +?> +<?php if (is_array($vars)): ?> + <?php foreach ($vars as $class => $field): ?> + <dl class="profile-category"> + <dt class="profile-<?php print $class; ?>"><?php print $field['title']; ?></dt> + <dd class="profile-<?php print $class; ?>"><?php print $field['value']; ?></dd> + </dl> + <?php endforeach; ?> +<?php endif; ?> diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_picture.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_picture.inc new file mode 100644 index 0000000000000000000000000000000000000000..978f3b539c482ff5bfd66fccc0cabd1d5b354894 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_picture.inc @@ -0,0 +1,48 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('User picture'), + 'icon' => 'icon_user.png', + 'description' => t('The picture of a user.'), + 'required context' => new ctools_context_required(t('User'), 'user'), + 'category' => t('User'), +); + +function ctools_user_picture_content_type_render($subtype, $conf, $panel_args, $context) { + $account = isset($context->data) ? drupal_clone($context->data) : NULL; + global $user; + + if (empty($context->data)) { + return; + } + + $account = drupal_clone($context->data); + + // Check if user has permissions to access the user + if ($user->uid != $account->uid && (!user_access('access user profiles') && !user_access('administer users'))) { + return; + } + + $block = new stdClass(); + $block->module = 'user-profile'; + $block->title = check_plain($account->name); + $block->content = theme('user_picture', $account); + + return $block; +} + +/** + * Display the administrative title for a panel pane in the drag & drop UI + */ +function ctools_user_picture_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" user picture', array('@s' => $context->identifier)); +} + +function ctools_user_picture_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_profile.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_profile.inc new file mode 100644 index 0000000000000000000000000000000000000000..7c14d42bfded59b612d6225a621e70e123a896a4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_profile.inc @@ -0,0 +1,45 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'single' => TRUE, + 'title' => t('User profile'), + 'icon' => 'icon_user.png', + 'description' => t('The profile of a user.'), + 'required context' => new ctools_context_required(t('User'), 'user'), + 'category' => t('User'), +); + +/** + * Render the user profile content type. + */ +function ctools_user_profile_content_type_render($subtype, $conf, $panel_args, $context) { + $account = isset($context->data) ? drupal_clone($context->data) : NULL; + if (!$account || ($account->access == 0 && !user_access('administer users'))) { + return NULL; + } + + // Retrieve all profile fields and attach to $account->content. + user_build_content($account); + + $block = new stdClass(); + $block->module = 'user-profile'; + $block->title = check_plain($account->name); + $block->content = theme('user_profile', $account); + + return $block; +} + +/** + * Display the administrative title for a panel pane in the drag & drop UI. + */ +function ctools_user_profile_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" user profile', array('@s' => $context->identifier)); +} + +function ctools_user_profile_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_signature.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_signature.inc new file mode 100644 index 0000000000000000000000000000000000000000..68d5b9933afa0d4fe53dd1c1f237c243e3b7b517 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/user_context/user_signature.inc @@ -0,0 +1,38 @@ +<?php + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('User signature'), + 'icon' => 'icon_user.png', + 'description' => t('The signature of a user.'), + 'required context' => new ctools_context_required(t('User'), 'user'), + 'category' => t('User'), +); + +function ctools_user_signature_content_type_render($subtype, $conf, $panel_args, $context) { + $account = isset($context->data) ? drupal_clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'term-list'; + + if ($account === FALSE || ($account->access == 0 && !user_access('administer users'))) { + return NULL; + } + + $block->content = theme('user_signature', $account->signature); + + return $block; +} + +/** + * Display the administrative title for a panel pane in the drag & drop UI + */ +function ctools_user_signature_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" user signature', array('@s' => $context->identifier)); +} + +function ctools_user_signature_content_type_edit_form(&$form, &$form_state) { + // provide a blank form so we have a place to have context setting. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/vocabulary_context/icon_vocabulary.png b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/vocabulary_context/icon_vocabulary.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/vocabulary_context/icon_vocabulary.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/vocabulary_context/vocabulary_terms.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/vocabulary_context/vocabulary_terms.inc new file mode 100644 index 0000000000000000000000000000000000000000..0fc366b322600a81b346f1184e763c94f14898b2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/content_types/vocabulary_context/vocabulary_terms.inc @@ -0,0 +1,93 @@ +<?php + +if (module_exists('taxonomy')) { + /** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ + $plugin = array( + 'single' => TRUE, + 'title' => t('Vocabulary terms'), + 'icon' => 'icon_vocabulary.png', + 'description' => t('All the terms in a vocabulary.'), + 'required context' => new ctools_context_required(t('Vocabulary'), 'vocabulary'), + 'category' => t('Vocabulary'), + 'defaults' => array('max_depth' => 0, 'tree' => 1), + ); +} + +/** + * Output function for the 'vocabulary terms' content type. Outputs a + * list of terms for the input vocabulary. + */ +function ctools_vocabulary_terms_content_type_render($subtype, $conf, $panel_args, $context) { + $vocab = isset($context->data) ? drupal_clone($context->data) : NULL; + $max_depth = (!empty($conf['max_depth']) ? (int)$conf['max_depth'] : NULL); + if ($conf['tree'] == FALSE) { + $terms = taxonomy_get_tree($vocab->vid, 0, -1, $max_depth); + $items = array(); + foreach ($terms as $term) { + $items[] = l($term->name, 'taxonomy/term/' . $term->tid); + } + $output = theme('item_list', $items); + } + else { + $output = theme('item_list', _ctools_content_vocabulary_terms($vocab->vid, $max_depth)); + } + + $block = new stdClass(); + $block->module = 'node_type'; + $block->title = check_plain($vocab->name); + $block->content = $output; + $block->delta = $vocab->vid; + + return $block; +} + +function _ctools_content_vocabulary_terms($vid, $max_depth, $depth = -1, $tid = 0) { + $depth++; + if ($max_depth != NULL && $depth == $max_depth) { + return array(); + } + $return = array(); + $query = db_query('SELECT t.name, t.tid FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE t.vid = %d AND h.parent = %d ORDER BY t.weight ASC, t.name ASC', $vid, $tid); + while ($result = db_fetch_object($query)) { + $return[] = array( + 'data' => l($result->name, 'taxonomy/term/'. $result->tid), + 'children' => _ctools_content_vocabulary_terms($vid, $max_depth, $depth, $result->tid), + ); + } + return $return; +} + +function ctools_vocabulary_terms_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" terms', array('@s' => $context->identifier)); +} + +function ctools_vocabulary_terms_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + $form['max_depth'] = array( + '#type' => 'select', + '#title' => t('Maximum depth'), + '#options' => array_merge(array(t('unlimited')), range(1, 9)), + '#default_value' => $conf['max_depth'], + '#description' => t('Define the maximum depth of terms being displayed.'), + ); + + $form['tree'] = array( + '#type' => 'checkbox', + '#title' => t('Display as tree'), + '#default_value' => $conf['tree'], + '#description' => t('If checked, the terms are displayed in a tree, otherwise in a flat list.'), + ); + + return $form; +} + +function ctools_vocabulary_terms_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node.inc new file mode 100644 index 0000000000000000000000000000000000000000..bba831197c5f25a3709b9c050e93a1a4a1a324e9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node.inc @@ -0,0 +1,212 @@ +<?php + +/** + * @file + * + * Plugin to provide a node context. A node context is a node wrapped in a + * context object that can be utilized by anything that accepts contexts. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Node"), + 'description' => t('A node object.'), + 'context' => 'ctools_context_create_node', + 'settings form' => 'ctools_context_node_settings_form', + 'settings form validate' => 'ctools_context_node_settings_form_validate', + 'settings form submit' => 'ctools_context_node_settings_form_submit', + 'defaults' => array('nid' => ''), + 'keyword' => 'node', + 'context name' => 'node', + 'convert list' => 'ctools_context_node_convert_list', + 'convert' => 'ctools_context_node_convert', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this context.'), + ), + 'placeholder name' => 'nid', +); + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_node($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('node'); + $context->plugin = 'node'; + + if ($empty) { + return $context; + } + + if ($conf) { + $nid = is_array($data) && isset($data['nid']) ? $data['nid'] : (is_object($data) ? $data->nid : 0); + + if (module_exists('translation')) { + if ($translation = module_invoke('translation', 'node_nid', $nid, $GLOBALS['language']->language)) { + $nid = $translation; + $reload = TRUE; + } + } + + if (is_array($data) || !empty($reload)) { + $data = node_load($nid); + } + } + + if (!empty($data)) { + $context->data = $data; + $context->title = $data->title; + $context->argument = $data->nid; + + $context->restrictions['type'] = array($data->type); + return $context; + } +} + +function ctools_context_node_settings_form($conf) { + if (empty($conf)) { + $conf = array( + 'nid' => '', + ); + } + + $form['node'] = array( + '#prefix' => '<div class="no-float">', + '#suffix' => '</div>', + '#title' => t('Enter the title or NID of a node'), + '#type' => 'textfield', + '#maxlength' => 512, + '#autocomplete_path' => 'ctools/autocomplete/node', + '#weight' => -10, + ); + + if (!empty($conf['nid'])) { + $info = db_fetch_object(db_query("SELECT * FROM {node} n WHERE n.nid = %d", $conf['nid'])); + if ($info) { + $link = l(t("'%title' [node id %nid]", array('%title' => $info->title, '%nid' => $info->nid)), "node/$info->nid", array('attributes' => array('target' => '_blank', 'title' => t('Open in new window')), 'html' => TRUE)); + $form['node']['#description'] = t('Currently set to !link', array('!link' => $link)); + } + } + + $form['nid'] = array( + '#type' => 'value', + '#value' => $conf['nid'], + ); + + $form['set_identifier'] = array( + '#type' => 'checkbox', + '#default_value' => FALSE, + '#title' => t('Reset identifier to node title'), + '#description' => t('If checked, the identifier will be reset to the node title of the selected node.'), + ); + + return $form; +} + +/** + * Validate a node. + */ +function ctools_context_node_settings_form_validate($form, &$form_values, &$form_state) { + // Validate the autocomplete + if (empty($form_values['nid']) && empty($form_values['node'])) { + form_error($form['node'], t('You must select a node.')); + return; + } + + if (empty($form_values['node'])) { + return; + } + + $nid = $form_values['node']; + $preg_matches = array(); + $match = preg_match('/\[nid: (\d+)\]/', $nid, $preg_matches); + if (!$match) { + $match = preg_match('/^nid: (\d+)/', $nid, $preg_matches); + } + + if ($match) { + $nid = $preg_matches[1]; + } + if (is_numeric($nid)) { + $node = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.nid = %d"), $nid)); + } + else { + $node = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE LOWER(n.title) = LOWER('%s')"), $nid)); + } + + // Do not allow unpublished nodes to be selected by unprivileged users + if (!$node || (empty($node->status) && !(user_access('administer nodes')))) { + form_error($form['node'], t('Invalid node selected.')); + } + else { + form_set_value($form['nid'], $node->nid, $form_state); + // $form_values['nid'] = $node->nid; + } +} + +function ctools_context_node_settings_form_submit($form, &$form_values, &$form_state) { + if ($form_values['set_identifier']) { + $node = node_load($form_values['nid']); + $form_state['values']['context']['identifier'] = $node->title; + } + + // Don't let this be stored. + unset($form_values['set_identifier']); +} + +/** + * Provide a list of ways that this context can be converted to a string. + */ +function ctools_context_node_convert_list() { + $list = array( + 'nid' => t('Node ID'), + 'vid' => t('Node revision ID'), + 'title' => t('Node title'), + 'uid' => t('Author UID'), + 'type' => t('Node type'), + ); + + // Include tokens provided by token.module. + if (module_exists('token')) { + foreach (token_get_list(array('node')) as $tokens) { + $readabletokens = array(); + foreach($tokens as $fieldname => $desc) { + $readabletokens[$fieldname] = $fieldname . ': ' . $desc; + } + $list += $readabletokens; + } + } + + return $list; +} + +/** + * Convert a context into a string. + */ +function ctools_context_node_convert($context, $type) { + switch ($type) { + case 'nid': + return $context->data->nid; + case 'vid': + return $context->data->vid; + case 'title': + return $context->data->title; + case 'uid': + return $context->data->uid; + case 'type': + return $context->data->type; + } + + // Check if token.module can provide the replacement. + if (module_exists('token')) { + $values = token_get_values('node', $context->data); + $key = array_search($type, $values->tokens); + if ($key !== FALSE) { + return $values->values[$key]; + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node_add_form.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node_add_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..c2eb3ef33335582a804927e3766d483e20e4d611 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node_add_form.inc @@ -0,0 +1,120 @@ +<?php + +/** + * @file + * + * Plugin to provide a node_add_form context + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Node add form"), + 'description' => t('A node add form.'), + 'context' => 'ctools_context_create_node_add_form', + 'settings form' => 'ctools_context_node_add_form_settings_form', + 'keyword' => 'node_add', + 'context name' => 'node_add_form', + 'convert list' => array('type' => t('Node type')), + 'convert' => 'ctools_context_node_add_form_convert', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node type this context.'), + ), +); + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_node_add_form($empty, $data = NULL, $conf = FALSE) { + static $creating = FALSE; + $context = new ctools_context(array('form', 'node_add', 'node_form')); + $context->plugin = 'node_add_form'; + + if ($empty || $creating) { + return $context; + } + $creating = TRUE; + + if ($conf && (isset($data['types']) || isset($data['type']))) { + // Holdover from typo'd config. + $data = isset($data['types']) ? $data['types'] : $data['type']; + } + + if (!empty($data)) { + $types = node_get_types(); + $type = str_replace('-', '_', $data); + + // Validate the node type exists. + if (isset($types[$type]) && node_access('create', $type)) { + // Initialize settings: + global $user; + $node = array('uid' => $user->uid, 'name' => $user->name, 'type' => $type); + + ctools_include('form'); + $form_id = $node['type'] . '_node_form'; + + $form_state = array('want form' => TRUE, 'args' => array($node)); + + $file = drupal_get_path('module', 'node') . '/node.pages.inc'; + include_once './' . $file; + // This piece of information can let other modules know that more files + // need to be included if this form is loaded from cache: + $form_state['form_load_files'] = array($file); + + $form = ctools_build_form($form_id, $form_state); + // In a form, $data is the object being edited. + $context->data = $type; + $context->title = $types[$type]->name; + $context->argument = $type; + + // These are specific pieces of data to this form. + // All forms should place the form here. + $context->form = $form; + $context->form_id = $type . '_node_form'; + $context->form_title = t('Submit @name', array('@name' => $types[$type]->name)); + $context->node_type = $type; + $context->restrictions['type'] = array($type); + $creating = FALSE; + return $context; + } + } + $creating = FALSE; +} + +function ctools_context_node_add_form_settings_form($conf) { + foreach (node_get_types() as $type => $info) { + $options[$type] = $info->name; + } + asort($options); + + if (isset($conf['types']) && !isset($conf['type'])) { + $conf['type'] = $conf['types']; + } + if (empty($conf)) { + $conf = array('type' => ''); + } + + $form['type'] = array( + '#title' => t('Node type'), + '#type' => 'select', + '#options' => $options, + '#default_value' => $conf['type'], + '#description' => t('Select the node type for this form.'), + ); + + return $form; +} + +/** + * Convert a context into a string. + */ +function ctools_context_node_add_form_convert($context, $type) { + switch ($type) { + case 'type': + return $context->data; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node_edit_form.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node_edit_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..540244e98e6b339c2ced28f7ac76f3ba6e652d4e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/node_edit_form.inc @@ -0,0 +1,201 @@ +<?php + +/** + * @file + * + * Plugin to provide a node_edit_form context + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Node edit form"), + 'description' => t('A node edit form.'), + 'context' => 'ctools_context_create_node_edit_form', + 'settings form' => 'ctools_context_node_edit_form_settings_form', + 'settings form validate' => 'ctools_context_node_edit_form_settings_form_validate', + 'settings form validate' => 'ctools_context_node_edit_form_settings_form_validate', + 'settings form submit' => 'ctools_context_node_edit_form_settings_form_submit', + 'defaults' => array('nid' => ''), + 'keyword' => 'node_edit', + 'context name' => 'node_edit_form', + 'convert list' => 'ctools_context_node_edit_convert_list', + 'convert' => 'ctools_context_node_edit_convert', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this argument:'), + ), +); + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_node_edit_form($empty, $node = NULL, $conf = FALSE) { + static $creating = FALSE; + $context = new ctools_context(array('form', 'node_edit', 'node_form', 'node', 'node_edit_form')); + $context->plugin = 'node_edit_form'; + + if ($empty || $creating) { + return $context; + } + $creating = TRUE; + + if ($conf) { + // In this case, $node is actually our $conf array. + $nid = is_array($node) && isset($node['nid']) ? $node['nid'] : (is_object($node) ? $node->nid : 0); + + if (module_exists('translation')) { + if ($translation = module_invoke('translation', 'node_nid', $nid, $GLOBALS['language']->language)) { + $nid = $translation; + $reload = TRUE; + } + } + + if (is_array($node) || !empty($reload)) { + $node = node_load($nid); + } + } + + if (!empty($node)) { + ctools_include('form'); + $form_id = $node->type . '_node_form'; + + $form_state = array('want form' => TRUE, 'args' => array($node)); + + $file = drupal_get_path('module', 'node') . '/node.pages.inc'; + include_once './' . $file; + // This piece of information can let other modules know that more files + // need to be included if this form is loaded from cache: + $form_state['form_load_files'] = array($file); + + $form = ctools_build_form($form_id, $form_state); + + // Fill in the 'node' portion of the context + $context->data = $node; + $context->title = $node->title; + $context->argument = isset($node->nid) ? $node->nid : $node->type; + + $context->form = $form; + $context->form_state = &$form_state; + $context->form_id = $form_id; + $context->form_title = $node->title; + $context->node_type = $node->type; + $context->restrictions['type'] = array($node->type); + $context->restrictions['form'] = array('form'); + + $creating = FALSE; + return $context; + } + $creating = FALSE; +} + +function ctools_context_node_edit_form_settings_form($conf) { + if (empty($conf)) { + $conf = array( + 'nid' => '', + ); + } + + $form['node'] = array( + '#prefix' => '<div class="no-float">', + '#suffix' => '</div>', + '#title' => t('Enter the title or NID of a node'), + '#type' => 'textfield', + '#maxlength' => 512, + '#autocomplete_path' => 'ctools/autocomplete/node', + '#weight' => -10, + ); + + if (!empty($conf['nid'])) { + $info = db_fetch_object(db_query("SELECT * FROM {node} n WHERE n.nid = %d", $conf['nid'])); + if ($info) { + $link = l(t("'%title' [node id %nid]", array('%title' => $info->title, '%nid' => $info->nid)), "node/$info->nid", array('attributes' => array('target' => '_blank', 'title' => t('Open in new window')), 'html' => TRUE)); + $form['node']['#description'] = t('Currently set to !link', array('!link' => $link)); + } + } + + $form['nid'] = array( + '#type' => 'value', + '#value' => $conf['nid'], + ); + + $form['set_identifier'] = array( + '#type' => 'checkbox', + '#default_value' => FALSE, + '#title' => t('Reset identifier to node title'), + '#description' => t('If checked, the identifier will be reset to the node title of the selected node.'), + ); + + return $form; +} + +/** + * Validate a node. + */ +function ctools_context_node_edit_form_settings_form_validate($form, &$form_values, &$form_state) { + // Validate the autocomplete + if (empty($form_values['nid']) && empty($form_values['node'])) { + form_error($form['node'], t('You must select a node.')); + return; + } + + if (empty($form_values['node'])) { + return; + } + + $nid = $form_values['node']; + $preg_matches = array(); + $match = preg_match('/\[nid: (\d+)\]/', $nid, $preg_matches); + if (!$match) { + $match = preg_match('/^nid: (\d+)/', $nid, $preg_matches); + } + + if ($match) { + $nid = $preg_matches[1]; + } + if (is_numeric($nid)) { + $node = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.nid = %d"), $nid)); + } + else { + $node = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE LOWER(n.title) = LOWER('%s')"), $nid)); + } + + if (!$node) { + form_error($form['node'], t('Invalid node selected.')); + } + else { + form_set_value($form['nid'], $node->nid, $form_state); + // $form_values['nid'] = $node->nid; + } +} + +function ctools_context_node_edit_form_settings_form_submit($form, &$form_values, &$form_state) { + if ($form_values['set_identifier']) { + $node = node_load($form_values['nid']); + $form_state['values']['context']['identifier'] = $node->title; + } + + // Don't let this be stored. + unset($form_values['set_identifier']); +} + +/** + * Provide a list of ways that this context can be converted to a string. + */ +function ctools_context_node_edit_convert_list() { + // Pass through to the "node" context convert list. + $plugin = ctools_get_context('node'); + return ctools_context_node_convert_list(); +} + +/** + * Convert a context into a string. + */ +function ctools_context_node_edit_convert($context, $type) { + // Pass through to the "node" context convert list. + $plugin = ctools_get_context('node'); + return ctools_context_node_convert($context, $type); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/string.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/string.inc new file mode 100644 index 0000000000000000000000000000000000000000..c53acaeacffe22f6c07c131ce4e425553d6ad07f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/string.inc @@ -0,0 +1,64 @@ +<?php + +/** + * @file + * + * Plugin to provide a string context + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('String'), + 'description' => t('A context that is just a string.'), + 'context' => 'ctools_context_create_string', + 'keyword' => 'string', + 'no ui' => TRUE, + 'context name' => 'string', + 'convert list' => array( + 'raw' => t('Raw string'), + 'html_safe' => t('HTML-safe string'), + ), + 'convert' => 'ctools_context_string_convert', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the string for this context.'), + ), +); + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_string($empty, $data = NULL, $conf = FALSE) { + // The input is expected to be an object as created by ctools_break_phrase + // which contains a group of string. + + $context = new ctools_context('string'); + $context->plugin = 'string'; + + if ($empty) { + return $context; + } + + if ($data !== FALSE ) { + $context->data = $data; + $context->title = check_plain($data); + return $context; + } +} + +/** + * Convert a context into a string. + */ +function ctools_context_string_convert($context, $type) { + switch ($type) { + case 'raw': + return $context->data; + case 'html_safe': + return check_plain($context->data); + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/term.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/term.inc new file mode 100644 index 0000000000000000000000000000000000000000..12714418f76946ac9db54acce412c0a5e23a29bd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/term.inc @@ -0,0 +1,174 @@ +<?php + +/** + * @file + * + * Plugin to provide a term context + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Taxonomy term"), + 'description' => t('A single taxonomy term object.'), + 'context' => 'ctools_context_create_term', + 'settings form' => 'ctools_context_term_settings_form', + 'settings form validate' => 'ctools_context_term_settings_form_validate', + 'settings form submit' => 'ctools_context_term_settings_form_submit', + 'keyword' => 'term', + 'context name' => 'term', + 'convert list' => array( + 'tid' => t('Term ID'), + 'name' => t('Term name'), + 'name_dashed' => t('Term name, lowercased and spaces converted to dashes'), + 'description' => t('Term Description'), + 'vid' => t('Vocabulary ID'), + ), + 'convert' => 'ctools_context_term_convert', + 'js' => array('misc/autocomplete.js'), +); + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_term($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('term'); + $context->plugin = 'term'; + + if ($empty) { + return $context; + } + + if ($conf && isset($data['tid'])) { + $data = taxonomy_get_term($data['tid']); + } + + if (!empty($data)) { + $context->data = $data; + $context->title = $data->name; + $context->argument = $data->tid; + $context->description = $data->description; + return $context; + } +} + +function ctools_context_term_settings_form($conf) { + if (empty($conf)) { + $conf = array( + 'vid' => '', + 'tid' => '', + 'term' => '', + 'description' => '', + ); + } + + $form['vid'] = array( + '#title' => t('Vocabulary'), + '#type' => 'select', + '#options' => array(), + '#description' => t('Select the vocabulary for this form.'), + '#id' => 'ctools-select-vid', + '#default_value' => $conf['vid'], + ); + + $description = ''; + if (!empty($conf['tid'])) { + $info = db_fetch_object(db_query("SELECT * FROM {term_data} n WHERE n.tid = %d", $conf['tid'])); + if ($info) { + $description = ' ' . t('Currently set to @term. Enter another term if you wish to change the term.', array('@term' => $info->name)); + } + } + + ctools_include('dependent'); + $options = array(); + + // A note: Dependency works strangely on these forms as they have never been + // updated to a more modern system so they are not individual forms of their + // own like the content types. + + $form['taxonomy']['#tree'] = TRUE; + + foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) { + $options[$vid] = $vocabulary->name; + $form['taxonomy'][$vocabulary->vid] = array( + '#type' => 'textfield', + '#description' => t('Select a term from @vocabulary.', array('@vocabulary' => $vocabulary->name)) . $description, + '#autocomplete_path' => 'taxonomy/autocomplete/' . $vocabulary->vid, + '#process' => array('ctools_dependent_process'), + '#dependency' => array('ctools-select-vid' => array($vocabulary->vid)), + ); + + } + + $form['vid']['#options'] = $options; + + $form['tid'] = array( + '#type' => 'value', + '#value' => $conf['tid'], + ); + + $form['set_identifier'] = array( + '#type' => 'checkbox', + '#default_value' => FALSE, + '#title' => t('Reset identifier to term title'), + '#description' => t('If checked, the identifier will be reset to the term name of the selected term.'), + ); + + return $form; +} + +/** + * Validate a term. + */ +function ctools_context_term_settings_form_validate($form, &$form_values, &$form_state) { + // Validate the autocomplete + $vid = $form_values['vid']; + if (empty($form_values['tid']) && empty($form_values['taxonomy'][$vid])) { + form_error($form['taxonomy'][$vid], t('You must select a term.')); + return; + } + + if (empty($form_values['taxonomy'][$vid])) { + return; + } + + $term = db_fetch_object(db_query("SELECT t.tid FROM {term_data} t WHERE LOWER(t.name) = LOWER('%s') AND t.vid = %d", $form_values['taxonomy'][$vid], $vid)); + + if (!$term) { + form_error($form['taxonomy'][$vid], t('Invalid term selected.')); + } + else { + form_set_value($form['tid'], $term->tid, $form_state); + } +} + +function ctools_context_term_settings_form_submit($form, &$form_values, &$form_state) { + if ($form_values['set_identifier']) { + $term = db_fetch_object(db_query("SELECT t.tid, t.name FROM {term_data} t WHERE LOWER(t.tid) = %d", $form_values['tid'])); + $form_state['values']['context']['identifier'] = $term->name; + } + + // Don't let this be stored. + unset($form_values['set_identifier']); +} + +/** + * Convert a context into a string. + */ +function ctools_context_term_convert($context, $type) { + switch ($type) { + case 'tid': + return $context->data->tid; + case 'name': + return $context->data->name; + case 'name_dashed': + return drupal_strtolower(str_replace(' ', '-', $context->data->name)); + case 'vid': + return $context->data->vid; + case 'description': + return $context->data->description; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/terms.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/terms.inc new file mode 100644 index 0000000000000000000000000000000000000000..a07a6c14ef919d079b749abc4744072f81f05ef2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/terms.inc @@ -0,0 +1,100 @@ +<?php + +/** + * @file + * + * Plugin to provide a terms context + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Taxonomy terms"), + 'description' => t('Multiple taxonomy terms, as a group.'), + 'context' => 'ctools_context_create_terms', + 'settings form' => 'ctools_context_terms_settings_form', + 'settings form validate' => 'ctools_context_terms_settings_form_validate', + 'keyword' => 'terms', + 'no ui' => TRUE, + 'context name' => 'terms', + 'convert list' => array( + 'tid' => t('Term ID of first term'), + 'tids' => t('Term ID of all term, separated by + or ,'), + 'name' => t('Term name of first term'), + 'name_dashed' => t('Term name of first term, lowercased and spaces converted to dashes'), + 'names' => t('Term name of all terms, separated by + or ,'), + 'names_dashed' => t('Term name of all terms, separated by + or , and lowercased and spaces converted to dashes'), + 'vid' => t('Vocabulary ID of first term'), + ), + 'convert' => 'ctools_context_terms_convert', +); + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_terms($empty, $data = NULL, $conf = FALSE) { + // The input is expected to be an object as created by ctools_break_phrase + // which contains a group of terms. + + $context = new ctools_context(array('terms', 'term')); + $context->plugin = 'terms'; + + if ($empty) { + return $context; + } + + if (!empty($data) && is_object($data)) { + $context->operator = $data->operator; + $context->tids = $data->value; + if (!isset($data->term)) { + // load the first term: + reset($context->tids); + $data->term = taxonomy_get_term(current($context->tids)); + } + $context->data = $data->term; + $context->title = $data->term->name; + $context->argument = implode($context->operator == 'or' ? '+' : ',', array_unique($context->tids)); + return $context; + } +} + +/** + * Convert a context into a string. + */ +function ctools_context_terms_convert($context, $type) { + switch ($type) { + case 'tid': + return $context->data->tid; + case 'tids': + return $context->argument; + case 'name': + return $context->data->name; + case 'name_dashed': + return drupal_strtolower(str_replace(' ', '-', $context->data->name)); + case 'names': + case 'names_dashed': + // We only run this query if this item was requested: + if (!isset($context->names)) { + if (empty($context->tids)) { + $context->names = ''; + } + else { + $names = array(); + $result = db_query("SELECT tid, name FROM {term_data} WHERE tid IN (" . db_placeholders($context->tids) . ")", $context->tids); + while ($term = db_fetch_object($result)) { + $names[$term->tid] = $term->name; + if ($type == 'names_dashed') { + $names[$term->tid] = drupal_strtolower(str_replace(' ', '-', $names[$term->tid])); + } + } + $context->names = implode($context->operator == 'or' ? ' + ' : ', ', $names); + } + } + return $context->names; + case 'vid': + return $context->data->vid; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/token.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/token.inc new file mode 100644 index 0000000000000000000000000000000000000000..e75916d1d36f1d14df6a183483ad1a4930071e19 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/token.inc @@ -0,0 +1,50 @@ +<?php + +/** + * @file + * Provide a global context to allow for token support. + */ + +if (module_exists('token')) { + $plugin = array( + 'title' => t('Token'), + 'description' => t('A context that contains token replacements from token.module.'), + 'context' => 'ctools_context_create_token', // func to create context + 'context name' => 'token', + 'keyword' => 'token', + 'convert list' => 'ctools_context_token_convert_list', + 'convert' => 'ctools_context_token_convert', + ); +} + +/** + * Create a context from manual configuration. + */ +function ctools_context_create_token($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('token'); + $context->plugin = 'token'; + + return $context; +} + +/** + * Implementation of hook_ctools_context_convert_list(). + */ +function ctools_context_token_convert_list() { + $list = array(); + foreach (token_get_list(array('global')) as $tokens) { + $list += $tokens; + } + return $list; +} + +/** + * Implementation of hook_ctools_context_converter_alter(). + */ +function ctools_context_token_convert($context, $type) { + $values = token_get_values('global'); + $key = array_search($type, $values->tokens); + if ($key !== FALSE) { + return $values->values[$key]; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/user.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/user.inc new file mode 100644 index 0000000000000000000000000000000000000000..bb94ac82ae1cddeec61e6a1443207099c69d704c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/user.inc @@ -0,0 +1,183 @@ +<?php + +/** + * @file + * + * Plugin to provide a user context + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("User"), + 'description' => t('A single user object.'), + 'context' => 'ctools_context_create_user', + 'settings form' => 'ctools_context_user_settings_form', + 'settings form validate' => 'ctools_context_user_settings_form_validate', + 'settings form submit' => 'ctools_context_user_settings_form_submit', + 'keyword' => 'user', + 'defaults' => array('type' => 'select', 'uid' => ''), + 'context name' => 'user', + 'convert list' => 'ctools_context_user_convert_list', + 'convert' => 'ctools_context_user_convert', + 'convert default' => 'name', + 'js' => array('misc/autocomplete.js'), +); + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_user($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('user'); + $context->plugin = 'user'; + + if ($empty) { + return $context; + } + + if ($conf) { + if ($data['type'] == 'current') { + global $user; + $data = $user; + if (user_is_logged_in()) { + $data->logged_in_user = TRUE; + } + } + else { + $data = user_load(array('uid' => $data['uid'])); + } + } + + if (!empty($data)) { + $context->data = $data; + $context->title = isset($data->name) ? $data->name : t('Anonymous'); + $context->argument = $data->uid; + return $context; + } +} + +function ctools_context_user_settings_form($conf) { + ctools_include('dependent'); + $form['type'] = array( + '#title' => t('Enter the context type'), + '#type' => 'radios', + '#options' => array( + 'select' => t('Select a user'), + 'current' => t('Logged in user'), + ), + '#default_value' => $conf['type'], + ); + + $form['user'] = array( + '#title' => t('Enter a user name'), + '#type' => 'textfield', + '#maxlength' => 512, + '#autocomplete_path' => 'user/autocomplete', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:context[context_settings][type]' => array('select')), + ); + + if (!empty($conf['uid'])) { + $info = user_load($conf['uid']); + if ($info) { + $form['user']['#description'] = t('Currently set to !link', array('!link' => theme('username', $info))); + } + } + + $form['uid'] = array( + '#type' => 'value', + '#value' => $conf['uid'], + ); + + $form['set_identifier'] = array( + '#type' => 'checkbox', + '#default_value' => FALSE, + '#title' => t('Reset identifier to username'), + '#description' => t('If checked, the identifier will be reset to the user name of the selected user.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:context[context_settings][type]' => array('select')), + ); + + return $form; +} + +/** + * Validate a user. + */ +function ctools_context_user_settings_form_validate($form, &$form_values, &$form_state) { + if ($form_values['type'] != 'select') { + return; + } + + // Validate the autocomplete + if (empty($form_values['uid']) && empty($form_values['user'])) { + form_error($form['user'], t('You must select a user.')); + return; + } + + if (empty($form_values['user'])) { + return; + } + + $account = user_load(array('name' => $form_values['user'])); + + if (!$account) { + form_error($form['user'], t('Invalid user selected.')); + } + else { + form_set_value($form['uid'], $account->uid, $form_state); + } +} + +function ctools_context_user_settings_form_submit($form, &$form_values, &$form_state) { + if ($form_values['set_identifier']) { + $account = user_load($form_values['uid']); + $form_state['values']['context']['identifier'] = $account->name; + } + + // Don't let this be stored. + unset($form_values['set_identifier']); +} + +/** + * Provide a list of replacements. + */ +function ctools_context_user_convert_list() { + $list = array( + 'uid' => t('User ID'), + 'name' => t('User name'), + ); + + // Include tokens provided by token.module. + if (module_exists('token')) { + foreach (token_get_list(array('user')) as $tokens) { + $list += $tokens; + } + } + + return $list; +} + +/** + * Convert a context into a string. + */ +function ctools_context_user_convert($context, $type) { + switch ($type) { + case 'uid': + return $context->data->uid; + case 'name': + return $context->data->name; + } + + // Check if token.module can provide the replacement. + if (module_exists('token')) { + $values = token_get_values('user', $context->data); + $key = array_search($type, $values->tokens); + if ($key !== FALSE) { + return $values->values[$key]; + } + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/vocabulary.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/vocabulary.inc new file mode 100644 index 0000000000000000000000000000000000000000..1d285d86d078b1d80a9c075258128a4edd9b0d63 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/contexts/vocabulary.inc @@ -0,0 +1,66 @@ +<?php + +/** + * @file + * + * Plugin to provide a vocabulary context + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Taxonomy vocabulary"), + 'description' => t('A single taxonomy vocabulary object.'), + 'context' => 'ctools_context_create_vocabulary', + 'settings form' => 'ctools_context_vocabulary_settings_form', + 'settings form validate' => 'ctools_context_vocabulary_settings_form_validate', + 'keyword' => 'vocabulary', + 'context name' => 'vocabulary', +); + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_vocabulary($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('vocabulary'); + $context->plugin = 'vocabulary'; + + if ($empty) { + return $context; + } + + if ($conf && isset($data['vid'])) { + $data = taxonomy_vocabulary_load($data['vid']); + } + + if (!empty($data)) { + $context->data = $data; + $context->title = $data->name; + $context->argument = $data->vid; + return $context; + } +} + +function ctools_context_vocabulary_settings_form($conf) { + $options = array(); + + foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) { + $options[$vid] = $vocabulary->name; + } + + $form['vid'] = array( + '#title' => t('Vocabulary'), + '#type' => 'select', + '#options' => $options, + '#default_value' => isset($conf['vid']) ? $conf['vid'] : array(), + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + '#description' => t('Select the vocabulary for this form.'), + ); + + return $form; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/export_ui/ctools_export_ui.class.php b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/export_ui/ctools_export_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..713677c5ec674f2503d1aadd7c17d0230791ce80 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/export_ui/ctools_export_ui.class.php @@ -0,0 +1,1464 @@ +<?php + +/** + * Base class for export UI. + */ +class ctools_export_ui { + var $plugin; + var $name; + var $options = array(); + + /** + * Fake constructor -- this is easier to deal with than the real + * constructor because we are retaining PHP4 compatibility, which + * would require all child classes to implement their own constructor. + */ + function init($plugin) { + ctools_include('export'); + + $this->plugin = $plugin; + } + + /** + * Get a page title for the current page from our plugin strings. + */ + function get_page_title($op, $item = NULL) { + if (empty($this->plugin['strings']['title'][$op])) { + return; + } + + // Replace %title that might be there with the exportable title. + $title = $this->plugin['strings']['title'][$op]; + if (!empty($item)) { + $export_key = $this->plugin['export']['key']; + $title = (str_replace('%title', check_plain($item->{$export_key}), $title)); + } + + return $title; + } + + /** + * Add text on the top of the page. + */ + function help_area($form_state) { + // If needed add advanced help strings. + $output = ''; + if (!empty($this->plugin['use advanced help'])) { + $config = $this->plugin['advanced help']; + if ($config['enabled']) { + $output = theme('advanced_help_topic', $config['module'], $config['topic']); + $output .= ' ' . $this->plugin['strings']['advanced help']['enabled']; + } + else { + $output = $this->plugin['strings']['advanced help']['disabled']; + } + } + return $output; + } + + // ------------------------------------------------------------------------ + // Menu item manipulation + + /** + * hook_menu() entry point. + * + * Child implementations that need to add or modify menu items should + * probably call parent::hook_menu($items) and then modify as needed. + */ + function hook_menu(&$items) { + // During upgrades, the schema can be empty as this is called prior to + // actual update functions being run. Ensure that we can cope with this + // situation. + if (empty($this->plugin['schema'])) { + return; + } + + $prefix = ctools_export_ui_plugin_base_path($this->plugin); + + if (isset($this->plugin['menu']['items']) && is_array($this->plugin['menu']['items'])) { + $my_items = array(); + foreach ($this->plugin['menu']['items'] as $item) { + // Add menu item defaults. + $item += array( + 'file' => 'export-ui.inc', + 'file path' => drupal_get_path('module', 'ctools') . '/includes', + ); + + $path = !empty($item['path']) ? $prefix . '/' . $item['path'] : $prefix; + unset($item['path']); + $my_items[$path] = $item; + } + $items += $my_items; + } + } + + /** + * Menu callback to determine if an operation is accessible. + * + * This function enforces a basic access check on the configured perm + * string, and then additional checks as needed. + * + * @param $op + * The 'op' of the menu item, which is defined by 'allowed operations' + * and embedded into the arguments in the menu item. + * @param $item + * If an op that works on an item, then the item object, otherwise NULL. + * + * @return + * TRUE if the current user has access, FALSE if not. + */ + function access($op, $item) { + if (!user_access($this->plugin['access'])) { + return FALSE; + } + + // More fine-grained access control: + if ($op == 'add' && !user_access($this->plugin['create access'])) { + return FALSE; + } + + // More fine-grained access control: + if (($op == 'revert' || $op == 'delete') && !user_access($this->plugin['delete access'])) { + return FALSE; + } + + // If we need to do a token test, do it here. + if (!empty($this->plugin['allowed operations'][$op]['token']) && (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], $op))) { + return FALSE; + } + + switch ($op) { + case 'import': + return user_access('use PHP for block visibility'); + case 'revert': + return ($item->export_type & EXPORT_IN_DATABASE) && ($item->export_type & EXPORT_IN_CODE); + case 'delete': + return ($item->export_type & EXPORT_IN_DATABASE) && !($item->export_type & EXPORT_IN_CODE); + case 'disable': + return empty($item->disabled); + case 'enable': + return !empty($item->disabled); + default: + return TRUE; + } + } + + // ------------------------------------------------------------------------ + // These methods are the API for generating the list of exportable items. + + /** + * Master entry point for handling a list. + * + * It is unlikely that a child object will need to override this method, + * unless the listing mechanism is going to be highly specialized. + */ + function list_page($js, $input) { + $this->items = ctools_export_crud_load_all($this->plugin['schema'], $js); + + // Respond to a reset command by clearing session and doing a drupal goto + // back to the base URL. + if (isset($input['op']) && $input['op'] == t('Reset')) { + unset($_SESSION['ctools_export_ui'][$this->plugin['name']]); + if (!$js) { + return drupal_goto($_GET['q']); + } + // clear everything but form id, form build id and form token: + $keys = array_keys($input); + foreach ($keys as $id) { + if (!in_array($id, array('form_id', 'form_build_id', 'form_token'))) { + unset($input[$id]); + } + } + $replace_form = TRUE; + } + + // If there is no input, check to see if we have stored input in the + // session. + if (!isset($input['form_id'])) { + if (isset($_SESSION['ctools_export_ui'][$this->plugin['name']]) && is_array($_SESSION['ctools_export_ui'][$this->plugin['name']])) { + $input = $_SESSION['ctools_export_ui'][$this->plugin['name']]; + } + } + else { + $_SESSION['ctools_export_ui'][$this->plugin['name']] = $input; + unset($_SESSION['ctools_export_ui'][$this->plugin['name']]['q']); + } + + // We rely on list_form_submit() to build the table rows. Clean out any + // AJAX markers that would prevent list_form() from automatically + // submitting the form. + if ($js) { + unset($input['js'], $input['ctools_ajax']); + } + + // This is where the form will put the output. + $this->rows = array(); + $this->sorts = array(); + + $form_state = array( + 'plugin' => $this->plugin, + 'input' => $input, + 'rerender' => TRUE, + 'no_redirect' => TRUE, + 'object' => &$this, + ); + + $help_area = $this->help_area($form_state); + + ctools_include('form'); + $form = ctools_build_form('ctools_export_ui_list_form', $form_state); + + $output = $this->list_header($form_state) . $this->list_render($form_state) . $this->list_footer($form_state); + + if (!$js) { + $this->list_css(); + return $help_area . $form . $output; + } + + ctools_include('ajax'); + $commands = array(); + $commands[] = ctools_ajax_command_replace('#ctools-export-ui-list-items', $output); + if (!empty($replace_form)) { + $commands[] = ctools_ajax_command_replace('#ctools-export-ui-list-form', $form); + } + ctools_ajax_render($commands); + } + + /** + * Create the filter/sort form at the top of a list of exports. + * + * This handles the very default conditions, and most lists are expected + * to override this and call through to parent::list_form() in order to + * get the base form and then modify it as necessary to add search + * gadgets for custom fields. + */ + function list_form(&$form, &$form_state) { + // This forces the form to *always* treat as submitted which is + // necessary to make it work. + $form['#token'] = FALSE; + if (empty($form_state['input'])) { + $form["#post"] = TRUE; + } + + // Add the 'q' in if we are not using clean URLs or it can get lost when + // using this kind of form. + if (!variable_get('clean_url', FALSE)) { + $form['q'] = array( + '#type' => 'hidden', + '#value' => $_GET['q'], + ); + } + + $all = array('all' => t('- All -')); + + $form['top row'] = array( + '#prefix' => '<div class="ctools-export-ui-row ctools-export-ui-top-row clear-block">', + '#suffix' => '</div>', + ); + + $form['bottom row'] = array( + '#prefix' => '<div class="ctools-export-ui-row ctools-export-ui-bottom-row clear-block">', + '#suffix' => '</div>', + ); + + $form['top row']['storage'] = array( + '#type' => 'select', + '#title' => t('Storage'), + '#options' => $all + array( + t('Normal') => t('Normal'), + t('Default') => t('Default'), + t('Overridden') => t('Overridden'), + ), + '#default_value' => 'all', + ); + + $form['top row']['disabled'] = array( + '#type' => 'select', + '#title' => t('Enabled'), + '#options' => $all + array( + '0' => t('Enabled'), + '1' => t('Disabled') + ), + '#default_value' => 'all', + ); + + $form['top row']['search'] = array( + '#type' => 'textfield', + '#title' => t('Search'), + ); + + $form['bottom row']['order'] = array( + '#type' => 'select', + '#title' => t('Sort by'), + '#options' => $this->list_sort_options(), + '#default_value' => 'disabled', + ); + + $form['bottom row']['sort'] = array( + '#type' => 'select', + '#title' => t('Order'), + '#options' => array( + 'asc' => t('Up'), + 'desc' => t('Down'), + ), + '#default_value' => 'asc', + ); + + $form['bottom row']['submit'] = array( + '#type' => 'submit', + '#id' => 'ctools-export-ui-list-items-apply', + '#value' => t('Apply'), + '#attributes' => array('class' => 'ctools-use-ajax ctools-auto-submit-click'), + ); + + $form['bottom row']['reset'] = array( + '#type' => 'submit', + '#id' => 'ctools-export-ui-list-items-apply', + '#value' => t('Reset'), + '#attributes' => array('class' => 'ctools-use-ajax'), + ); + + ctools_add_js('ajax-responder'); + ctools_add_js('auto-submit'); + drupal_add_js('misc/jquery.form.js'); + + $form['#prefix'] = '<div class="clear-block">'; + $form['#suffix'] = '</div>'; + $form['#attributes'] = array('class' => 'ctools-auto-submit-full-form'); + } + + /** + * Validate the filter/sort form. + * + * It is very rare that a filter form needs validation, but if it is + * needed, override this. + */ + function list_form_validate(&$form, &$form_state) { } + + /** + * Submit the filter/sort form. + * + * This submit handler is actually responsible for building up all of the + * rows that will later be rendered, since it is doing the filtering and + * sorting. + * + * For the most part, you should not need to override this method, as the + * fiddly bits call through to other functions. + */ + function list_form_submit(&$form, &$form_state) { + // Filter and re-sort the pages. + $plugin = $this->plugin; + $schema = ctools_export_get_schema($this->plugin['schema']); + + $prefix = ctools_export_ui_plugin_base_path($plugin); + + foreach ($this->items as $name => $item) { + // Call through to the filter and see if we're going to render this + // row. If it returns TRUE, then this row is filtered out. + if ($this->list_filter($form_state, $item)) { + continue; + } + + // Note: Creating this list seems a little clumsy, but can't think of + // better ways to do this. + $allowed_operations = drupal_map_assoc(array_keys($plugin['allowed operations'])); + $not_allowed_operations = array('import'); + + if ($item->{$schema['export']['export type string']} == t('Normal')) { + $not_allowed_operations[] = 'revert'; + } + elseif ($item->{$schema['export']['export type string']} == t('Overridden')) { + $not_allowed_operations[] = 'delete'; + } + else { + $not_allowed_operations[] = 'revert'; + $not_allowed_operations[] = 'delete'; + } + + $not_allowed_operations[] = empty($item->disabled) ? 'enable' : 'disable'; + + foreach ($not_allowed_operations as $op) { + // Remove the operations that are not allowed for the specific + // exportable. + unset($allowed_operations[$op]); + } + + $operations = array(); + + foreach ($allowed_operations as $op) { + $operations[$op] = array( + 'title' => $plugin['allowed operations'][$op]['title'], + 'href' => ctools_export_ui_plugin_menu_path($plugin, $op, $name), + ); + if (!empty($plugin['allowed operations'][$op]['ajax'])) { + $operations[$op]['attributes'] = array('class' => 'ctools-use-ajax'); + } + if (!empty($plugin['allowed operations'][$op]['token'])) { + $operations[$op]['query'] = array('token' => drupal_get_token($op)); + } + } + + $this->list_build_row($item, $form_state, $operations); + } + + // Now actually sort + if ($form_state['values']['sort'] == 'desc') { + arsort($this->sorts); + } + else { + asort($this->sorts); + } + + // Nuke the original. + $rows = $this->rows; + $this->rows = array(); + // And restore. + foreach ($this->sorts as $name => $title) { + $this->rows[$name] = $rows[$name]; + } + } + + /** + * Determine if a row should be filtered out. + * + * This handles the default filters for the export UI list form. If you + * added additional filters in list_form() then this is where you should + * handle them. + * + * @return + * TRUE if the item should be excluded. + */ + function list_filter($form_state, $item) { + $schema = ctools_export_get_schema($this->plugin['schema']); + if ($form_state['values']['storage'] != 'all' && $form_state['values']['storage'] != $item->{$schema['export']['export type string']}) { + return TRUE; + } + + if ($form_state['values']['disabled'] != 'all' && $form_state['values']['disabled'] != !empty($item->disabled)) { + return TRUE; + } + + if ($form_state['values']['search']) { + $search = strtolower($form_state['values']['search']); + foreach ($this->list_search_fields() as $field) { + if (strpos(strtolower($item->$field), $search) !== FALSE) { + $hit = TRUE; + break; + } + } + if (empty($hit)) { + return TRUE; + } + } + } + + /** + * Provide a list of fields to test against for the default "search" widget. + * + * This widget will search against whatever fields are configured here. By + * default it will attempt to search against the name, title and description fields. + */ + function list_search_fields() { + $fields = array( + $this->plugin['export']['key'], + ); + + if (!empty($this->plugin['export']['admin_title'])) { + $fields[] = $this->plugin['export']['admin_title']; + } + if (!empty($this->plugin['export']['admin_description'])) { + $fields[] = $this->plugin['export']['admin_description']; + } + + return $fields; + } + + /** + * Provide a list of sort options. + * + * Override this if you wish to provide more or change how these work. + * The actual handling of the sorting will happen in build_row(). + */ + function list_sort_options() { + if (!empty($this->plugin['export']['admin_title'])) { + $options = array( + 'disabled' => t('Enabled, title'), + $this->plugin['export']['admin_title'] => t('Title'), + ); + } + else { + $options = array( + 'disabled' => t('Enabled, name'), + ); + } + + $options += array( + 'name' => t('Name'), + 'storage' => t('Storage'), + ); + + return $options; + } + + /** + * Add listing CSS to the page. + * + * Override this if you need custom CSS for your list. + */ + function list_css() { + ctools_add_css('export-ui-list'); + } + + /** + * Build a row based on the item. + * + * By default all of the rows are placed into a table by the render + * method, so this is building up a row suitable for theme('table'). + * This doesn't have to be true if you override both. + */ + function list_build_row($item, &$form_state, $operations) { + // Set up sorting + $name = $item->{$this->plugin['export']['key']}; + $schema = ctools_export_get_schema($this->plugin['schema']); + + // Note: $item->{$schema['export']['export type string']} should have already been set up by export.inc so + // we can use it safely. + switch ($form_state['values']['order']) { + case 'disabled': + $this->sorts[$name] = empty($item->disabled) . $name; + break; + case 'title': + $this->sorts[$name] = $item->{$this->plugin['export']['admin_title']}; + break; + case 'name': + $this->sorts[$name] = $name; + break; + case 'storage': + $this->sorts[$name] = $item->{$schema['export']['export type string']} . $name; + break; + } + + $this->rows[$name]['data'] = array(); + $this->rows[$name]['class'] = !empty($item->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled'; + + // If we have an admin title, make it the first row. + if (!empty($this->plugin['export']['admin_title'])) { + $this->rows[$name]['data'][] = array('data' => check_plain($item->{$this->plugin['export']['admin_title']}), 'class' => 'ctools-export-ui-title'); + } + $this->rows[$name]['data'][] = array('data' => check_plain($name), 'class' => 'ctools-export-ui-name'); + $this->rows[$name]['data'][] = array('data' => check_plain($item->{$schema['export']['export type string']}), 'class' => 'ctools-export-ui-storage'); + $this->rows[$name]['data'][] = array('data' => theme('links', $operations), 'class' => 'ctools-export-ui-operations'); + + // Add an automatic mouseover of the description if one exists. + if (!empty($this->plugin['export']['admin_description'])) { + $this->rows[$name]['title'] = $item->{$this->plugin['export']['admin_description']}; + } + } + + /** + * Provide the table header. + * + * If you've added columns via list_build_row() but are still using a + * table, override this method to set up the table header. + */ + function list_table_header() { + $header = array(); + if (!empty($this->plugin['export']['admin_title'])) { + $header[] = array('data' => t('Title'), 'class' => 'ctools-export-ui-title'); + } + + $header[] = array('data' => t('Name'), 'class' => 'ctools-export-ui-name'); + $header[] = array('data' => t('Storage'), 'class' => 'ctools-export-ui-storage'); + $header[] = array('data' => t('Operations'), 'class' => 'ctools-export-ui-operations'); + + return $header; + } + + /** + * Render all of the rows together. + * + * By default we place all of the rows in a table, and this should be the + * way most lists will go. + * + * Whatever you do if this method is overridden, the ID is important for AJAX + * so be sure it exists. + */ + function list_render(&$form_state) { + return theme('table', $this->list_table_header(), $this->rows, array('id' => 'ctools-export-ui-list-items')); + } + + /** + * Render a header to go before the list. + * + * This will appear after the filter/sort widgets. + */ + function list_header($form_state) { } + + /** + * Render a footer to go after thie list. + * + * This is a good place to add additional links. + */ + function list_footer($form_state) { } + + // ------------------------------------------------------------------------ + // These methods are the API for adding/editing exportable items + + function add_page($js, $input, $step = NULL) { + drupal_set_title($this->get_page_title('add')); + + // If a step not set, they are trying to create a new item. If a step + // is set, they're in the process of creating an item. + if (!empty($this->plugin['use wizard']) && !empty($step)) { + $item = $this->edit_cache_get(NULL, 'add'); + } + if (empty($item)) { + $item = ctools_export_crud_new($this->plugin['schema']); + } + + $form_state = array( + 'plugin' => $this->plugin, + 'object' => &$this, + 'ajax' => $js, + 'item' => $item, + 'op' => 'add', + 'form type' => 'add', + 'rerender' => TRUE, + 'no_redirect' => TRUE, + 'step' => $step, + // Store these in case additional args are needed. + 'function args' => func_get_args(), + ); + + $output = $this->edit_execute_form($form_state); + if (!empty($form_state['executed'])) { + $export_key = $this->plugin['export']['key']; + drupal_goto(str_replace('%ctools_export_ui', $form_state['item']->{$export_key}, $this->plugin['redirect']['add'])); + } + + return $output; + } + + /** + * Main entry point to edit an item. + */ + function edit_page($js, $input, $item, $step = NULL) { + drupal_set_title($this->get_page_title('edit', $item)); + + // Check to see if there is a cached item to get if we're using the wizard. + if (!empty($this->plugin['use wizard'])) { + $cached = $this->edit_cache_get($item, 'edit'); + if (!empty($cached)) { + $item = $cached; + } + } + + $form_state = array( + 'plugin' => $this->plugin, + 'object' => &$this, + 'ajax' => $js, + 'item' => $item, + 'op' => 'edit', + 'form type' => 'edit', + 'rerender' => TRUE, + 'no_redirect' => TRUE, + 'step' => $step, + // Store these in case additional args are needed. + 'function args' => func_get_args(), + ); + + $output = $this->edit_execute_form($form_state); + if (!empty($form_state['executed'])) { + $export_key = $this->plugin['export']['key']; + drupal_goto(str_replace('%ctools_export_ui', $form_state['item']->{$export_key}, $this->plugin['redirect']['edit'])); + } + + return $output; + } + + /** + * Main entry point to clone an item. + */ + function clone_page($js, $input, $original, $step = NULL) { + drupal_set_title($this->get_page_title('clone', $original)); + + // If a step not set, they are trying to create a new clone. If a step + // is set, they're in the process of cloning an item. + if (!empty($this->plugin['use wizard']) && !empty($step)) { + $item = $this->edit_cache_get(NULL, 'clone'); + } + if (empty($item)) { + // To make a clone of an item, we first export it and then re-import it. + // Export the handler, which is a fantastic way to clean database IDs out of it. + $export = ctools_export_crud_export($this->plugin['schema'], $original); + $item = ctools_export_crud_import($this->plugin['schema'], $export); + $item->{$this->plugin['export']['key']} = 'clone_of_' . $item->{$this->plugin['export']['key']}; + } + + // Tabs and breadcrumb disappearing, this helps alleviate through cheating. + ctools_include('menu'); + $trail = ctools_get_menu_trail(ctools_export_ui_plugin_base_path($this->plugin)); + menu_set_active_trail($trail); + $name = $original->{$this->plugin['export']['key']}; + + $form_state = array( + 'plugin' => $this->plugin, + 'object' => &$this, + 'ajax' => $js, + 'item' => $item, + 'op' => 'add', + 'form type' => 'clone', + 'original name' => $name, + 'rerender' => TRUE, + 'no_redirect' => TRUE, + 'step' => $step, + // Store these in case additional args are needed. + 'function args' => func_get_args(), + ); + + $output = $this->edit_execute_form($form_state); + if (!empty($form_state['executed'])) { + $export_key = $this->plugin['export']['key']; + drupal_goto(str_replace('%ctools_export_ui', $form_state['item']->{$export_key}, $this->plugin['redirect']['clone'])); + } + + return $output; + } + + /** + * Execute the form. + * + * Add and Edit both funnel into this, but they have a few different + * settings. + */ + function edit_execute_form(&$form_state) { + if (!empty($this->plugin['use wizard'])) { + return $this->edit_execute_form_wizard($form_state); + } + else { + return $this->edit_execute_form_standard($form_state); + } + } + + /** + * Execute the standard form for editing. + * + * By default, export UI will provide a single form for editing an object. + */ + function edit_execute_form_standard(&$form_state) { + ctools_include('form'); + $output = ctools_build_form('ctools_export_ui_edit_item_form', $form_state); + if (!empty($form_state['executed'])) { + $this->edit_save_form($form_state); + } + + return $output; + } + + /** + * Get the form info for the wizard. + * + * This gets the form info out of the plugin, then adds defaults based on + * how we want edit forms to work. + * + * Overriding this can allow child UIs to tweak this info for specialized + * wizards. + * + * @param array $form_state + * The already created form state. + */ + function get_wizard_info(&$form_state) { + if (!isset($form_state['step'])) { + $form_state['step'] = NULL; + } + + $export_key = $this->plugin['export']['key']; + + // When cloning, the name of the item being cloned is referenced in the + // path, not the name of this item. + if ($form_state['form type'] == 'clone') { + $name = $form_state['original name']; + } + else { + $name = $form_state['item']->{$export_key}; + } + + $form_info = !empty($this->plugin['form info']) ? $this->plugin['form info'] : array(); + $form_info += array( + 'id' => 'ctools_export_ui_edit', + 'path' => ctools_export_ui_plugin_menu_path($this->plugin, $form_state['form type'], $name) . '/%step', + 'show trail' => TRUE, + 'free trail' => TRUE, + 'show back' => $form_state['form type'] == 'add', + 'show return' => FALSE, + 'show cancel' => TRUE, + 'finish callback' => 'ctools_export_ui_wizard_finish', + 'next callback' => 'ctools_export_ui_wizard_next', + 'back callback' => 'ctools_export_ui_wizard_back', + 'cancel callback' => 'ctools_export_ui_wizard_cancel', + 'order' => array(), + 'import order' => array( + 'import' => t('Import code'), + 'settings' => t('Settings'), + ), + ); + + // Set the order of forms based on the op if we have a specific one. + if (isset($form_info[$form_state['form type'] . ' order'])) { + $form_info['order'] = $form_info[$form_state['form type'] . ' order']; + } + + // We have generic fallback forms we can use if they are not specified, + // and they automatically delegate back to the UI object. Use these if + // not specified. + foreach ($form_info['order'] as $key => $title) { + if (empty($form_info['forms'][$key])) { + $form_info['forms'][$key] = array( + 'form id' => 'ctools_export_ui_edit_item_wizard_form', + ); + } + } + + // 'free trail' means the wizard can freely go back and form from item + // via the trail and not with next/back buttons. + if ($form_state['form type'] == 'add' || ($form_state['form type'] == 'import' && empty($form_state['item']->{$export_key}))) { + $form_info['free trail'] = FALSE; + } + + return $form_info; + } + + /** + * Execute the wizard for editing. + * + * For complex objects, sometimes a wizard is needed. This is normally + * activated by setting 'use wizard' => TRUE in the plugin definition + * and then creating a 'form info' array to feed the wizard the data + * it needs. + * + * When creating this wizard, the plugin is responsible for defining all forms + * that will be utilized with the wizard. + * + * Using 'add order' or 'edit order' can be used to ensure that add/edit order + * is different. + */ + function edit_execute_form_wizard(&$form_state) { + $form_info = $this->get_wizard_info($form_state); + + // If there aren't any forms set, fail. + if (empty($form_info['order'])) { + return MENU_NOT_FOUND; + } + + // Figure out if this is a new instance of the wizard + if (empty($form_state['step'])) { + $form_state['step'] = reset(array_keys($form_info['order'])); + } + + if (empty($form_info['order'][$form_state['step']]) && empty($form_info['forms'][$form_state['step']])) { + return MENU_NOT_FOUND; + } + + ctools_include('wizard'); + $output = ctools_wizard_multistep_form($form_info, $form_state['step'], $form_state); + if (!empty($form_state['complete'])) { + $this->edit_save_form($form_state); + } + else if ($output && !empty($form_state['item']->export_ui_item_is_cached)) { + // @todo this should be in the plugin strings + drupal_set_message(t('You have unsaved changes. These changes will not be made permanent until you click <em>Save</em>.'), 'warning'); + } + + // Unset the executed flag if any non-wizard button was pressed. Those + // buttons require special handling by whatever client is operating them. + if (!empty($form_state['executed']) && empty($form_state['clicked_button']['#wizard type'])) { + unset($form_state['executed']); + } + return $output; + } + + /** + * Wizard 'back' callback when using a wizard to edit an item. + * + * The wizard callback delegates this back to the object. + */ + function edit_wizard_back(&$form_state) { + // This only exists so child implementations can use it. + } + + /** + * Wizard 'next' callback when using a wizard to edit an item. + * + * The wizard callback delegates this back to the object. + */ + function edit_wizard_next(&$form_state) { + $this->edit_cache_set($form_state['item'], $form_state['form type']); + } + + /** + * Wizard 'cancel' callback when using a wizard to edit an item. + * + * The wizard callback delegates this back to the object. + */ + function edit_wizard_cancel(&$form_state) { + $this->edit_cache_clear($form_state['item'], $form_state['form type']); + } + + /** + * Wizard 'cancel' callback when using a wizard to edit an item. + * + * The wizard callback delegates this back to the object. + */ + function edit_wizard_finish(&$form_state) { + $form_state['complete'] = TRUE; + + // If we are importing, and overwrite was selected, delete the original so + // that this one writes properly. + if ($form_state['form type'] == 'import' && !empty($form_state['item']->export_ui_allow_overwrite)) { + ctools_export_crud_delete($this->plugin['schema'], $form_state['item']); + } + + $this->edit_cache_clear($form_state['item'], $form_state['form type']); + } + + /** + * Retrieve the item currently being edited from the object cache. + */ + function edit_cache_get($item, $op = 'edit') { + ctools_include('object-cache'); + if (is_string($item)) { + $name = $item; + } + else { + $name = $this->edit_cache_get_key($item, $op); + } + + $cache = ctools_object_cache_get('ctui_' . $this->plugin['name'], $name); + if ($cache) { + $cache->export_ui_item_is_cached = TRUE; + return $cache; + } + } + + /** + * Cache the item currently currently being edited. + */ + function edit_cache_set($item, $op = 'edit') { + ctools_include('object-cache'); + $name = $this->edit_cache_get_key($item, $op); + return $this->edit_cache_set_key($item, $name); + } + + function edit_cache_set_key($item, $name) { + return ctools_object_cache_set('ctui_' . $this->plugin['name'], $name, $item); + } + + /** + * Clear the object cache for the currently edited item. + */ + function edit_cache_clear($item, $op = 'edit') { + ctools_include('object-cache'); + $name = $this->edit_cache_get_key($item, $op); + return ctools_object_cache_clear('ctui_' . $this->plugin['name'], $name); + } + + /** + * Figure out what the cache key is for this object. + */ + function edit_cache_get_key($item, $op) { + $export_key = $this->plugin['export']['key']; + return $op == 'edit' ? $item->{$this->plugin['export']['key']} : "::$op"; + } + + /** + * Called to save the final product from the edit form. + */ + function edit_save_form($form_state) { + $item = &$form_state['item']; + $export_key = $this->plugin['export']['key']; + + $result = ctools_export_crud_save($this->plugin['schema'], $item); + + if ($result) { + $message = str_replace('%title', check_plain($item->{$export_key}), $this->plugin['strings']['confirmation'][$form_state['op']]['success']); + drupal_set_message($message); + } + else { + $message = str_replace('%title', check_plain($item->{$export_key}), $this->plugin['strings']['confirmation'][$form_state['op']]['fail']); + drupal_set_message($message, 'error'); + } + } + + /** + * Provide the actual editing form. + */ + function edit_form(&$form, &$form_state) { + $export_key = $this->plugin['export']['key']; + $item = $form_state['item']; + $schema = ctools_export_get_schema($this->plugin['schema']); + + // TODO: Drupal 7 has a nifty method of auto guessing names from + // titles that is standard. We should integrate that here as a + // nice standard. + // Guess at a couple of our standard fields. + if (!empty($this->plugin['export']['admin_title'])) { + $form['info'][$this->plugin['export']['admin_title']] = array( + '#type' => 'textfield', + '#title' => t('Administrative title'), + '#description' => t('This will appear in the administrative interface to easily identify it.'), + '#default_value' => $item->{$this->plugin['export']['admin_title']}, + ); + } + + $form['info'][$export_key] = array( + '#title' => t($schema['export']['key name']), + '#type' => 'textfield', + '#default_value' => $item->{$export_key}, + '#description' => t('The unique ID for this @export.', array('@export' => $this->plugin['title singular'])), + '#required' => TRUE, + '#maxlength' => 255, + ); + + if ($form_state['op'] === 'edit') { + $form['info'][$export_key]['#disabled'] = TRUE; + $form['info'][$export_key]['#value'] = $item->{$export_key}; + } + else { + $form['info'][$export_key]['#element_validate'] = array('ctools_export_ui_edit_name_validate'); + } + + if (!empty($this->plugin['export']['admin_description'])) { + $form['info'][$this->plugin['export']['admin_description']] = array( + '#type' => 'textarea', + '#title' => t('Administrative description'), + '#default_value' => $item->{$this->plugin['export']['admin_description']}, + ); + } + + // Add plugin's form definitions. + if (!empty($this->plugin['form']['settings'])) { + // Pass $form by reference. + $this->plugin['form']['settings']($form, $form_state); + } + + // Add the buttons if the wizard is not in use. + if (empty($form_state['form_info'])) { + // Make sure that whatever happens, the buttons go to the bottom. + $form['buttons']['#weight'] = 100; + + // Add buttons. + $form['buttons']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + $form['buttons']['delete'] = array( + '#type' => 'submit', + '#value' => $item->export_type & EXPORT_IN_CODE ? t('Revert') : t('Delete'), + '#access' => $form_state['op'] === 'edit' && $item->export_type & EXPORT_IN_DATABASE, + '#submit' => array('ctools_export_ui_edit_item_form_delete'), + ); + } + } + + /** + * Validate callback for the edit form. + */ + function edit_form_validate(&$form, &$form_state) { + if (!empty($this->plugin['form']['validate'])) { + // Pass $form by reference. + $this->plugin['form']['validate']($form, $form_state); + } + } + + /** + * Perform a final validation check before allowing the form to be + * finished. + */ + function edit_finish_validate(&$form, &$form_state) { + if ($form_state['op'] != 'edit') { + // Validate the name. Fake an element for form_error(). + $export_key = $this->plugin['export']['key']; + $element = array( + '#value' => $form_state['item']->{$export_key}, + '#parents' => array('name'), + ); + $form_state['plugin'] = $this->plugin; + ctools_export_ui_edit_name_validate($element, $form_state); + } + } + + /** + * Handle the submission of the edit form. + * + * At this point, submission is successful. Our only responsibility is + * to copy anything out of values onto the item that we are able to edit. + * + * If the keys all match up to the schema, this method will not need to be + * overridden. + */ + function edit_form_submit(&$form, &$form_state) { + if (!empty($this->plugin['form']['submit'])) { + // Pass $form by reference. + $this->plugin['form']['submit']($form, $form_state); + } + + // Transfer data from the form to the $item based upon schema values. + $schema = ctools_export_get_schema($this->plugin['schema']); + foreach (array_keys($schema['fields']) as $key) { + if(isset($form_state['values'][$key])) { + $form_state['item']->{$key} = $form_state['values'][$key]; + } + } + } + + // ------------------------------------------------------------------------ + // These methods are the API for 'other' stuff with exportables such as + // enable, disable, import, export, delete + + /** + * Callback to enable a page. + */ + function enable_page($js, $input, $item) { + return $this->set_item_state(FALSE, $js, $input, $item); + } + + /** + * Callback to disable a page. + */ + function disable_page($js, $input, $item) { + return $this->set_item_state(TRUE, $js, $input, $item); + } + + /** + * Set an item's state to enabled or disabled and output to user. + * + * If javascript is in use, this will rebuild the list and send that back + * as though the filter form had been executed. + */ + function set_item_state($state, $js, $input, $item) { + ctools_export_set_object_status($item, $state); + + if (!$js) { + drupal_goto(ctools_export_ui_plugin_base_path($this->plugin)); + } + else { + return $this->list_page($js, $input); + } + } + + /** + * Page callback to delete an exportable item. + */ + function delete_page($js, $input, $item) { + $form_state = array( + 'plugin' => $this->plugin, + 'object' => &$this, + 'ajax' => $js, + 'item' => $item, + 'op' => $item->export_type & EXPORT_IN_CODE ? 'revert' : 'delete', + 'rerender' => TRUE, + 'no_redirect' => TRUE, + ); + + ctools_include('form'); + + $output = ctools_build_form('ctools_export_ui_delete_confirm_form', $form_state); + if (!empty($form_state['executed'])) { + ctools_export_crud_delete($this->plugin['schema'], $item); + $export_key = $this->plugin['export']['key']; + $message = str_replace('%title', check_plain($item->{$export_key}), $this->plugin['strings']['confirmation'][$form_state['op']]['success']); + drupal_set_message($message); + drupal_goto(ctools_export_ui_plugin_base_path($this->plugin)); + } + + return $output; + } + + /** + * Page callback to display export information for an exportable item. + */ + function export_page($js, $input, $item) { + drupal_set_title($this->get_page_title('export', $item)); + return drupal_get_form('ctools_export_form', ctools_export_crud_export($this->plugin['schema'], $item), t('Export')); + } + + /** + * Page callback to import information for an exportable item. + */ + function import_page($js, $input, $step = NULL) { + drupal_set_title($this->get_page_title('import')); + // Import is basically a multi step wizard form, so let's go ahead and + // use CTools' wizard.inc for it. + + // If a step not set, they are trying to create a new item. If a step + // is set, they're in the process of creating an item. + if (!empty($step)) { + $item = $this->edit_cache_get(NULL, 'import'); + } + if (empty($item)) { + $item = ctools_export_crud_new($this->plugin['schema']); + } + + $form_state = array( + 'plugin' => $this->plugin, + 'object' => &$this, + 'ajax' => $js, + 'item' => $item, + 'op' => 'add', + 'form type' => 'import', + 'rerender' => TRUE, + 'no_redirect' => TRUE, + 'step' => $step, + // Store these in case additional args are needed. + 'function args' => func_get_args(), + ); + + // import always uses the wizard. + $output = $this->edit_execute_form_wizard($form_state); + if (!empty($form_state['executed'])) { + $export_key = $this->plugin['export']['key']; + drupal_goto(str_replace('%ctools_export_ui', $form_state['item']->{$export_key}, $this->plugin['redirect']['add'])); + } + + return $output; + } + + /** + * Import form. Provides simple helptext instructions and textarea for + * pasting a export definition. + */ + function edit_form_import(&$form, &$form_state) { + $form['help'] = array( + '#type' => 'item', + '#value' => $this->plugin['strings']['help']['import'], + ); + + $form['import'] = array( + '#title' => t('@plugin code', array('@plugin' => $this->plugin['title singular proper'])), + '#type' => 'textarea', + '#rows' => 10, + '#required' => TRUE, + '#default_value' => !empty($form_state['item']->export_ui_code) ? $form_state['item']->export_ui_code : '', + ); + + $form['overwrite'] = array( + '#title' => t('Allow import to overwrite an existing record.'), + '#type' => 'checkbox', + '#default_value' => !empty($form_state['item']->export_ui_allow_overwrite) ? $form_state['item']->export_ui_allow_overwrite : FALSE, + ); + } + + /** + * Import form validate handler. + * + * Evaluates code and make sure it creates an object before we continue. + */ + function edit_form_import_validate($form, &$form_state) { + $item = ctools_export_crud_import($this->plugin['schema'], $form_state['values']['import']); + if (is_string($item)) { + form_error($form['import'], t('Unable to get an import from the code. Errors reported: @errors', array('@errors' => $item))); + return; + } + + $form_state['item'] = $item; + $form_state['item']->export_ui_allow_overwrite = $form_state['values']['overwrite']; + $form_state['item']->export_ui_code = $form_state['values']['import']; + } + + /** + * Submit callback for import form. + * + * Stores the item in the session. + */ + function edit_form_import_submit($form, &$form_state) { + // The validate function already imported and stored the item. This + // function exists simply to prevent it from going to the default + // edit_form_submit() method. + } +} + +// ----------------------------------------------------------------------- +// Forms to be used with this class. +// +// Since Drupal's forms are completely procedural, these forms will +// mostly just be pass-throughs back to the object. + +/** + * Form callback to handle the filter/sort form when listing items. + * + * This simply loads the object defined in the plugin and hands it off. + */ +function ctools_export_ui_list_form(&$form_state) { + $form = array(); + $form_state['object']->list_form($form, $form_state); + return $form; +} + +/** + * Validate handler for ctools_export_ui_list_form. + */ +function ctools_export_ui_list_form_validate(&$form, &$form_state) { + $form_state['object']->list_form_validate($form, $form_state); +} + +/** + * Submit handler for ctools_export_ui_list_form. + */ +function ctools_export_ui_list_form_submit(&$form, &$form_state) { + $form_state['object']->list_form_submit($form, $form_state); +} + +/** + * Form callback to edit an exportable item. + * + * This simply loads the object defined in the plugin and hands it off. + */ +function ctools_export_ui_edit_item_form(&$form_state) { + $form = array(); + $form_state['object']->edit_form($form, $form_state); + return $form; +} + +/** + * Validate handler for ctools_export_ui_edit_item_form. + */ +function ctools_export_ui_edit_item_form_validate(&$form, &$form_state) { + $form_state['object']->edit_form_validate($form, $form_state); +} + +/** + * Submit handler for ctools_export_ui_edit_item_form. + */ +function ctools_export_ui_edit_item_form_submit(&$form, &$form_state) { + $form_state['object']->edit_form_submit($form, $form_state); +} + +/** + * Submit handler to delete for ctools_export_ui_edit_item_form + * + * @todo Put this on a callback in the object. + */ +function ctools_export_ui_edit_item_form_delete(&$form, &$form_state) { + $export_key = $form_state['plugin']['export']['key']; + $path = $form_state['item']->export_type & EXPORT_IN_CODE ? 'revert' : 'delete'; + + drupal_goto(ctools_export_ui_plugin_menu_path($form_state['plugin'], $path, $form_state['item']->{$export_key}), array('cancel_path' => $_GET['q'])); +} + +/** + * Validate that an export item name is acceptable and unique during add. + */ +function ctools_export_ui_edit_name_validate($element, &$form_state) { + $plugin = $form_state['plugin']; + // Check for string identifier sanity + if (!preg_match('!^[a-z0-9_]+$!', $element['#value'])) { + form_error($element, t('The export id can only consist of lowercase letters, underscores, and numbers.')); + return; + } + + // Check for name collision + if (empty($form_state['item']->export_ui_allow_overwrite) && $exists = ctools_export_crud_load($plugin['schema'], $element['#value'])) { + form_error($element, t('A @plugin with this name already exists. Please choose another name or delete the existing item before creating a new one.', array('@plugin' => $plugin['title singular']))); + } +} + +/** + * Delete/Revert confirm form. + * + * @todo -- call back into the object instead. + */ +function ctools_export_ui_delete_confirm_form(&$form_state) { + $plugin = $form_state['plugin']; + $item = $form_state['item']; + + $form = array(); + + $export_key = $plugin['export']['key']; + $question = str_replace('%title', check_plain($item->{$export_key}), $plugin['strings']['confirmation'][$form_state['op']]['question']); + $path = (!empty($_REQUEST['cancel_path']) && !menu_path_is_external($_REQUEST['cancel_path'])) ? $_REQUEST['cancel_path'] : ctools_export_ui_plugin_base_path($plugin); + + $form = confirm_form($form, + $question, + $path, + $plugin['strings']['confirmation'][$form_state['op']]['information'], + $plugin['allowed operations'][$form_state['op']]['title'], t('Cancel') + ); + return $form; +} + +// -------------------------------------------------------------------------- +// Forms and callbacks for using the edit system with the wizard. + +/** + * Form callback to edit an exportable item using the wizard + * + * This simply loads the object defined in the plugin and hands it off. + */ +function ctools_export_ui_edit_item_wizard_form(&$form, &$form_state) { + $method = 'edit_form_' . $form_state['step']; + if (!method_exists($form_state['object'], $method)) { + $method = 'edit_form'; + } + + $form_state['object']->$method($form, $form_state); + return $form; +} + +/** + * Validate handler for ctools_export_ui_edit_item_wizard_form. + */ +function ctools_export_ui_edit_item_wizard_form_validate(&$form, &$form_state) { + $method = 'edit_form_' . $form_state['step'] . '_validate'; + if (!method_exists($form_state['object'], $method)) { + $method = 'edit_form_validate'; + } + + $form_state['object']->$method($form, $form_state); + + // Additionally, if there were no errors from that, and we're finishing, + // perform a final validate to make sure everything is ok. + if (isset($form_state['clicked_button']['#wizard type']) && $form_state['clicked_button']['#wizard type'] == 'finish' && !form_get_errors()) { + $form_state['object']->edit_finish_validate($form, $form_state); + } +} + +/** + * Submit handler for ctools_export_ui_edit_item_wizard_form. + */ +function ctools_export_ui_edit_item_wizard_form_submit(&$form, &$form_state) { + $method = 'edit_form_' . $form_state['step'] . '_submit'; + if (!method_exists($form_state['object'], $method)) { + $method = 'edit_form_submit'; + } + + $form_state['object']->$method($form, $form_state); +} + +/** + * Wizard 'back' callback when using a wizard to edit an item. + */ +function ctools_export_ui_wizard_back(&$form_state) { + $form_state['object']->edit_wizard_back($form_state); +} + +/** + * Wizard 'next' callback when using a wizard to edit an item. + */ +function ctools_export_ui_wizard_next(&$form_state) { + $form_state['object']->edit_wizard_next($form_state); +} + +/** + * Wizard 'cancel' callback when using a wizard to edit an item. + */ +function ctools_export_ui_wizard_cancel(&$form_state) { + $form_state['object']->edit_wizard_cancel($form_state); +} + +/** + * Wizard 'finish' callback when using a wizard to edit an item. + */ +function ctools_export_ui_wizard_finish(&$form_state) { + $form_state['object']->edit_wizard_finish($form_state); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/export_ui/ctools_export_ui.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/export_ui/ctools_export_ui.inc new file mode 100644 index 0000000000000000000000000000000000000000..4e0a84978ee1b219c8f5fbf7edfed3666f0269fd --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/export_ui/ctools_export_ui.inc @@ -0,0 +1,24 @@ +<?php + +/** + * The default plugin exists only to provide the base class. Other plugins + * which do not provide a class will get this class instead. Any classes + * provided should use this class as their parent: + * + * @code + * 'handler' => array( + * 'class' => 'ctools_export_ui_mine', + * 'parent' => 'ctools_export_ui', + * ), + * @endcode + * + * Using the above notation will ensure that this plugin's is loaded before + * the child plugin's class and avoid whitescreens. + */ +$plugin = array( + // As this is the base class plugin, it shouldn't declare any menu items. + 'has menu' => FALSE, + 'handler' => array( + 'class' => 'ctools_export_ui', + ), +); diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/book_parent.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/book_parent.inc new file mode 100644 index 0000000000000000000000000000000000000000..11fa45bade45081744ca995b7b3031fb45a63048 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/book_parent.inc @@ -0,0 +1,65 @@ +<?php + +/** + * @file + * Plugin to provide an relationship handler for book parent. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Book parent'), + 'keyword' => 'book_parent', + 'description' => t('Adds a book parent from a node context.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'context' => 'ctools_book_parent_context', + 'settings form' => 'ctools_book_parent_settings_form', + 'settings form validate' => 'ctools_book_parent_settings_form_validate', + 'defaults' => array('type' => 'top'), +); + +/** + * Return a new context based on an existing context. + */ +function ctools_book_parent_context($context, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data)) { + return ctools_context_create_empty('node'); + } + + if (isset($context->data->book)) { + if ($conf['type'] == 'top') { + $nid = $context->data->book['bid']; + } + else { + // Just load the parent book. + $item = book_link_load($context->data->book['plid']); + $nid = $item['nid']; + } + + if (!empty($nid)) { + // Load the node. + $node = node_load($nid); + // Generate the context. + if (node_access('view', $node)) { + return ctools_context_create('node', $node); + } + } + } +} + +/** + * Settings form for the relationship. + */ +function ctools_book_parent_settings_form($conf) { + $form['type'] = array( + '#type' => 'select', + '#title' => t('Relationship type'), + '#options' => array('parent' => t('Immediate parent'), 'top' => t('Top level book')), + '#default_value' => $conf['type'], + ); + + return $form; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/node_edit_form_from_node.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/node_edit_form_from_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..8aaaeaf4ff04e9fbbd732939e796fbfbd12d6022 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/node_edit_form_from_node.inc @@ -0,0 +1,39 @@ +<?php + +/** + * @file + * Plugin to provide an relationship handler for term from node. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Node edit form from node'), + 'keyword' => 'node_form', + 'description' => t('Adds node edit form from a node context.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'context' => 'ctools_node_edit_form_from_node_context', + 'settings form' => 'ctools_node_edit_form_from_node_settings_form', +); + +/** + * Return a new context based on an existing context. + */ +function ctools_node_edit_form_from_node_context($context, $conf) { + if (empty($context->data)) { + return ctools_context_create_empty('node_edit_form', NULL); + } + + if (isset($context->data->nid)) { + return ctools_context_create('node_edit_form', $context->data); + } +} + +/** + * Settings form for the relationship. + */ +function ctools_node_edit_form_from_node_settings_form($conf) { + // This function intentionally left blank. +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/term_from_node.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/term_from_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..9bb8f2cd3a4d0dbcbc606e6dbc4d39c828c14614 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/term_from_node.inc @@ -0,0 +1,59 @@ +<?php + +/** + * @file + * Plugin to provide an relationship handler for term from node. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Term from node'), + 'keyword' => 'term', + 'description' => t('Adds a taxonomy term from a node context; if multiple terms are selected, this will get the "first" term only.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'context' => 'ctools_term_from_node_context', + 'settings form' => 'ctools_term_from_node_settings_form', + 'settings form validate' => 'ctools_term_from_node_settings_form_validate', + 'defaults' => array('vid' => ''), +); + +/** + * Return a new context based on an existing context. + */ +function ctools_term_from_node_context($context, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data)) { + return ctools_context_create_empty('term', NULL); + } + + if (isset($context->data->taxonomy)) { + foreach ($context->data->taxonomy as $term) { + if ($term->vid == $conf['vid']) { + return ctools_context_create('term', $term); + } + } + } +} + +/** + * Settings form for the relationship. + */ +function ctools_term_from_node_settings_form($conf) { + $options = array(); + foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) { + $options[$vid] = $vocabulary->name; + } + $form['vid'] = array( + '#title' => t('Vocabulary'), + '#type' => 'select', + '#options' => $options, + '#default_value' => $conf['vid'], + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + + return $form; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/term_parent.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/term_parent.inc new file mode 100644 index 0000000000000000000000000000000000000000..3ecd7960701e96d06b3c8dcb315f9b19dc831432 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/term_parent.inc @@ -0,0 +1,66 @@ +<?php + +/** + * @file relationships/term_parent.inc + * Plugin to provide an relationship handler for term parent. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Term parent'), + 'keyword' => 'parent_term', + 'description' => t('Adds a taxonomy term parent from a term context.'), + 'required context' => new ctools_context_required(t('Term'), 'term'), + 'context' => 'ctools_term_parent_context', + 'settings form' => 'ctools_term_parent_settings_form', + 'settings form validate' => 'ctools_term_parent_settings_form_validate', +); + +/** + * Return a new context based on an existing context. + */ +function ctools_term_parent_context($context, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data)) { + return ctools_context_create_empty('term'); + } + + if (isset($context->data)) { + $result = db_fetch_array(db_query("SELECT t1.* FROM {term_hierarchy} t1 INNER JOIN {term_hierarchy} t2 ON t1.tid = t2.parent WHERE t2.tid = %d", $context->data->tid)); + + // If top level term, keep looking up until we see a top level. + if ($conf['type'] == 'top') { + // If looking for top level, and there are no parents at all, make sure + // the current term is the 'top level'. + if (empty($result)) { + $result['tid'] = $context->data->tid; + } + while (!empty($result['parent'])) { + $result = db_fetch_array(db_query("SELECT * FROM {term_hierarchy} WHERE tid = %d", $result['parent'])); + } + } + + // Load the term. + if ($result) { + $term = taxonomy_get_term($result['tid']); + return ctools_context_create('term', $term); + } + } +} + +/** + * Settings form for the relationship. + */ +function ctools_term_parent_settings_form($conf) { + $form['type'] = array( + '#type' => 'select', + '#title' => t('Relationship type'), + '#options' => array('parent' => t('Immediate parent'), 'top' => t('Top level term')), + '#default_value' => $conf['type'], + ); + + return $form; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/terms_from_node.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/terms_from_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..23062a1d1975e16503afaa4b5041bb4486e47be8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/terms_from_node.inc @@ -0,0 +1,75 @@ +<?php + +/** + * @file + * Plugin to provide an relationship handler for all terms from node. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Multiple terms from node'), + 'keyword' => 'terms', + 'description' => t('Adds a taxonomy terms from a node context; if multiple terms are selected, they wil be concatenated.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'context' => 'ctools_terms_from_node_context', + 'settings form' => 'ctools_terms_from_node_settings_form', + 'settings form validate' => 'ctools_terms_from_node_settings_form_validate', + 'defaults' => array('vid' => array(), 'concatenator' => ','), +); + +/** + * Return a new context based on an existing context. + */ +function ctools_terms_from_node_context($context, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data)) { + return ctools_context_create_empty('terms', NULL); + } + + // Collect all terms for the chosen vocabulary and concatenate them. + if (isset($context->data->taxonomy)) { + $terms = array(); + foreach ($context->data->taxonomy as $term) { + if (in_array($term->vid, $conf['vid'])) { + $terms[] = $term->tid; + } + } + + if (!empty($terms)) { + $all_terms = ctools_break_phrase(implode($conf['concatenator'], $terms)); + return ctools_context_create('terms', $all_terms); + } + } +} + +/** + * Settings form for the relationship. + */ +function ctools_terms_from_node_settings_form($conf) { + $options = array(); + foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) { + $options[$vid] = $vocabulary->name; + } + $form['vid'] = array( + '#title' => t('Vocabulary'), + '#type' => 'checkboxes', + '#options' => $options, + '#default_value' => $conf['vid'], + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + $form['concatenator'] = array( + '#title' => t('Concatenator'), + '#type' => 'select', + '#options' => array(',' => ', (AND)', '+' => '+ (OR)'), + '#default_value' => $conf['concatenator'], + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + '#description' => t("When the value from this context is passed on to a view as argument, the terms can be concatenated in the form of 1+2+3 (for OR) or 1,2,3 (for AND)."), + ); + + return $form; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/user_from_node.inc b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/user_from_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..c22df7552d360d33ea653bd48a831965eccef591 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/plugins/relationships/user_from_node.inc @@ -0,0 +1,37 @@ +<?php + +/** + * @file + * Plugin to provide an relationship handler for node from user. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Node author'), + 'keyword' => 'user', + 'description' => t('Creates the author of a node as a user context.'), + 'required context' => new ctools_context_required(t('Node'), 'node'), + 'context' => 'ctools_user_from_node_context', +); + +/** + * Return a new context based on an existing context. + */ +function ctools_user_from_node_context($context, $conf) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data) || !isset($context->data->uid)) { + return ctools_context_create_empty('user', NULL); + } + + if (isset($context->data->uid)) { + // Load the user that is the author of the node. + $uid = $context->data->uid; + $account = user_load(array('uid' => $uid)); + + // Send it to ctools. + return ctools_context_create('user', $account); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/help/base-style-types.html b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/help/base-style-types.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/help/base-styles.html b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/help/base-styles.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/help/stylizer.help.ini b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/help/stylizer.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/plugins/export_ui/stylizer.inc b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/plugins/export_ui/stylizer.inc new file mode 100644 index 0000000000000000000000000000000000000000..a5826b8adf89f1ea5a8ddc51dafa345f87a23999 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/plugins/export_ui/stylizer.inc @@ -0,0 +1,46 @@ +<?php + +$plugin = array( + 'schema' => 'stylizer', + 'access' => 'administer stylizer', + + 'menu' => array( + 'menu item' => 'stylizer', + 'menu title' => 'Stylizer', + 'menu description' => 'Add, edit or delete stylizer styles.', + ), + + 'title singular' => t('style'), + 'title singular proper' => t('Style'), + 'title plural' => t('styles'), + 'title plural proper' => t('Styles'), + + 'handler' => array( + 'class' => 'stylizer_ui', + 'parent' => 'ctools_export_ui', + ), + + 'strings' => array( + 'message' => array( + 'missing base type' => t('There are currently no style types available to add. You should enable a module that utilizes them, such as Panels.'), + ), + ), + + 'use wizard' => TRUE, + 'form info' => array( + 'add order' => array( + 'admin' => t('Administrative settings'), + 'type' => t('Select style type'), + 'choose' => t('Select base style'), + ), + 'order' => array( + 'admin' => t('Administrative settings'), + ), + 'forms' => array( + 'choose' => array( + 'form id' => 'ctools_stylizer_edit_style_form_choose', + ), + ), + ), +); + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/plugins/export_ui/stylizer_ui.class.php b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/plugins/export_ui/stylizer_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..2abf6977486d7e96111a1cc6c6f63f4716538012 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/plugins/export_ui/stylizer_ui.class.php @@ -0,0 +1,270 @@ +<?php + +/** + * UI class for Stylizer. + */ +class stylizer_ui extends ctools_export_ui { + + function access($op, $item) { + $access = parent::access($op, $item); + if ($op == 'add' && $access && empty($this->base_types)) { + // Make sure there are base styles defined. + $access = FALSE; + } + return $access; + } + + function list_form(&$form, &$form_state) { + ctools_include('stylizer'); + parent::list_form($form, $form_state); + + $all = array('all' => t('- All -')); + + if (empty($this->base_types)) { + // Give a warning about the missing base styles. + drupal_set_message($this->plugin['strings']['message']['missing base type'], 'warning'); + } + + $types = $all; + foreach ($this->base_types as $module => $info) { + foreach ($info as $key => $base_type) { + $types[$module . '-' . $key] = $base_type['title']; + } + } + + $form['top row']['type'] = array( + '#type' => 'select', + '#title' => t('Type'), + '#options' => $types, + '#default_value' => 'all', + '#weight' => -10, + '#attributes' => array('class' => 'ctools-auto-submit'), + ); + + $plugins = ctools_get_style_bases(); + $form_state['style_plugins'] = $plugins; + + $options = $all; + // @todo base should use $module . '-' . $name + foreach ($plugins as $name => $plugin) { + $options[$name] = $plugin['title']; + } + + $form['top row']['base'] = array( + '#type' => 'select', + '#title' => t('Base'), + '#options' => $all + $options, + '#default_value' => 'all', + '#weight' => -9, + '#attributes' => array('class' => 'ctools-auto-submit'), + ); + } + + function list_sort_options() { + return array( + 'disabled' => t('Enabled, title'), + 'title' => t('Title'), + 'name' => t('Name'), + 'base' => t('Base'), + 'type' => t('Type'), + 'storage' => t('Storage'), + ); + } + + function list_filter($form_state, $item) { + if (empty($form_state['style_plugins'][$item->settings['style_base']])) { + $this->style_plugin = array( + 'name' => 'broken', + 'title' => t('Missing plugin'), + 'type' => t('Unknown'), + 'module' => '', + ); + } + else { + $this->style_plugin = $form_state['style_plugins'][$item->settings['style_base']]; + } + + // This isn't really a field, but by setting this we can list it in the + // filter fields and have the search box pick it up. + $item->plugin_title = $this->style_plugin['title']; + + if ($form_state['values']['type'] != 'all') { + list($module, $type) = explode('-', $form_state['values']['type']); + if ($module != $this->style_plugin['module'] || $type != $this->style_plugin['type']) { + return TRUE; + } + } + + if ($form_state['values']['base'] != 'all' && $form_state['values']['base'] != $this->style_plugin['name']) { + return TRUE; + } + + return parent::list_filter($form_state, $item); + } + + function list_search_fields() { + $fields = parent::list_search_fields(); + $fields[] = 'plugin_title'; + return $fields; + } + + function list_build_row($item, &$form_state, $operations) { + // Set up sorting + switch ($form_state['values']['order']) { + case 'disabled': + $this->sorts[$item->name] = empty($item->disabled) . $item->admin_title; + break; + case 'title': + $this->sorts[$item->name] = $item->admin_title; + break; + case 'name': + $this->sorts[$item->name] = $item->name; + break; + case 'type': + $this->sorts[$item->name] = $this->style_plugin['type'] . $item->admin_title; + break; + case 'base': + $this->sorts[$item->name] = $this->style_plugin['title'] . $item->admin_title; + break; + case 'storage': + $this->sorts[$item->name] = $item->type . $item->admin_title; + break; + } + + if (!empty($this->base_types[$this->style_plugin['module']][$this->style_plugin['type']])) { + $type = $this->base_types[$this->style_plugin['module']][$this->style_plugin['type']]['title']; + } + else { + $type = t('Unknown'); + } + + $this->rows[$item->name] = array( + 'data' => array( + array('data' => $type, 'class' => 'ctools-export-ui-type'), + array('data' => check_plain($item->name), 'class' => 'ctools-export-ui-name'), + array('data' => check_plain($item->admin_title), 'class' => 'ctools-export-ui-title'), + array('data' => check_plain($this->style_plugin['title']), 'class' => 'ctools-export-ui-base'), + array('data' => check_plain($item->type), 'class' => 'ctools-export-ui-storage'), + array('data' => theme('links', $operations), 'class' => 'ctools-export-ui-operations'), + ), + 'title' => check_plain($item->admin_description), + 'class' => !empty($item->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled', + ); + } + + function list_table_header() { + return array( + array('data' => t('Type'), 'class' => 'ctools-export-ui-type'), + array('data' => t('Name'), 'class' => 'ctools-export-ui-name'), + array('data' => t('Title'), 'class' => 'ctools-export-ui-title'), + array('data' => t('Base'), 'class' => 'ctools-export-ui-base'), + array('data' => t('Storage'), 'class' => 'ctools-export-ui-storage'), + array('data' => t('Operations'), 'class' => 'ctools-export-ui-operations'), + ); + } + + function init($plugin) { + ctools_include('stylizer'); + $this->base_types = ctools_get_style_base_types(); + + parent::init($plugin); + } + + function get_wizard_info(&$form_state) { + $form_info = parent::get_wizard_info($form_state); + ctools_include('stylizer'); + + // For add forms, we have temporarily set the 'form type' to include + // the style type so the default wizard_info can find the path. If + // we did that, we have to put it back. + if (!empty($form_state['type'])) { + $form_state['form type'] = 'add'; + $form_info['show back'] = TRUE; + } + + // Ensure these do not get out of sync. + $form_state['item']->settings['name'] = $form_state['item']->name; + $form_state['settings'] = $form_state['item']->settings; + + // Figure out the base style plugin in use and make sure that is available. + $plugin = NULL; + if (!empty($form_state['item']->settings['style_base'])) { + $plugin = ctools_get_style_base($form_state['item']->settings['style_base']); + ctools_stylizer_add_plugin_forms($form_info, $plugin, $form_state['op']); + } + else { + // This is here so the 'finish' button does not show up, and because + // we don't have the selected style we don't know what the next form(s) + // will be. + $form_info['order']['next'] = t('Configure style'); + + } + + // If available, make sure these are available for the 'choose' form. + if (!empty($form_state['item']->style_module)) { + $form_state['module'] = $form_state['item']->style_module; + $form_state['type'] = $form_state['item']->style_type; + } + + $form_state['plugin'] = $plugin; + $form_state['settings'] = $form_state['item']->settings; + return $form_info; + } + + /** + * Store the stylizer info in our settings. + * + * The stylizer wizard stores its stuff in slightly different places, so + * we have to find it and move it to the right place. + */ + function store_stylizer_info(&$form_state) { + /* + foreach (array('name', 'admin_title', 'admin_description') as $key) { + if (!empty($form_state['values'][$key])) { + $form_state['item']->{$key} = $form_state['values'][$key]; + } + } + */ + + if ($form_state['step'] != 'import') { + $form_state['item']->settings = $form_state['settings']; + } + // Do not let the 'name' accidentally get out of sync under any circumstances. + $form_state['item']->settings['name'] = $form_state['item']->name; + } + + function edit_wizard_next(&$form_state) { + $this->store_stylizer_info($form_state); + parent::edit_wizard_next($form_state); + } + + function edit_wizard_finish(&$form_state) { + // These might be stored by the stylizer wizard, so we should clear them. + if (isset($form_state['settings']['old_settings'])) { + unset($form_state['settings']['old_settings']); + } + $this->store_stylizer_info($form_state); + parent::edit_wizard_finish($form_state); + } + + function edit_form_type(&$form, &$form_state) { + foreach ($this->base_types as $module => $info) { + foreach ($info as $key => $base_type) { + $types[$module . '-' . $key] = $base_type['title']; + } + } + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Type'), + '#options' => $types, + '#default_value' => 'all', + '#weight' => -10, + '#attributes' => array('class' => 'ctools-auto-submit'), + ); + } + + function edit_form_type_submit(&$form, &$form_state) { + list($form_state['item']->style_module, $form_state['item']->style_type) = explode('-', $form_state['values']['type']); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.info b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.info new file mode 100644 index 0000000000000000000000000000000000000000..cad1f8bbdddefcfe35540aff8bfb606b5039247b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.info @@ -0,0 +1,12 @@ +name = Stylizer +description = Create custom styles for applications such as Panels. +core = 6.x +package = Chaos tool suite +dependencies[] = ctools + +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.install b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.install new file mode 100644 index 0000000000000000000000000000000000000000..a91c4ea662f23d0919bf1e66ff4d2319508dca9f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.install @@ -0,0 +1,84 @@ +<?php + +/** + * Schema for stylizer. + */ +function stylizer_schema() { + return stylizer_schema_1(); +} + +function stylizer_schema_1() { + $schema = array(); + + $schema['stylizer'] = array( + 'description' => 'Customized stylizer styles created by administrative users.', + 'export' => array( + 'bulk export' => TRUE, + 'export callback' => 'stylizer_style_export', + 'can disable' => TRUE, + 'identifier' => 'style', + 'primary key' => 'sid', + ), + 'fields' => array( + 'sid' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'no export' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this style. Used to identify it programmatically.', + ), + 'admin_title' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Human readable title for this style.', + ), + 'admin_description' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Administrative description of this style.', + 'object default' => '', + ), + 'settings' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array( + 'name' => '_temporary', + 'style_base' => NULL, + 'palette' => array(), + ), + 'description' => 'A serialized array of settings specific to the style base that describes this plugin.', + ), + ), + 'primary key' => array('sid'), + 'unique keys' => array( + 'name' => array('name'), + ), + ); + + return $schema; +} + +/** + * Implementation of hook_install(). + */ +function stylizer_install() { + $ret = array(); + if (db_table_exists('panels_style')) { + db_rename_table($ret, 'panels_style', 'stylizer'); + } + else { + drupal_install_schema('stylizer'); + } +} + +/** + * Implementation of hook_uninstall(). + */ +function stylizer_uninstall() { + drupal_uninstall_schema('stylizer'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.module b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.module new file mode 100644 index 0000000000000000000000000000000000000000..fa0b40637bb2f842a68ceef62fc9fcf56f180d01 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/stylizer/stylizer.module @@ -0,0 +1,90 @@ +<?php + +/** + * @file + * Stylizer module + * + * This module allows styles to be created and managed on behalf of modules + * that implement styles. + * + * The Stylizer tool allows recolorable styles to be created via a miniature + * scripting language. Panels utilizes this to allow administrators to add + * styles directly to any panel display. + */ + +/** + * Implementation of hook_perm() + */ +function stylizer_perm() { + return array( + 'administer stylizer', + ); +} + +/** + * Implementation of hook_ctools_plugin_directory() to let the system know + * we implement task and task_handler plugins. + */ +function stylizer_ctools_plugin_directory($module, $plugin) { + // Most of this module is implemented as an export ui plugin, and the + // rest is in ctools/includes/stylizer.inc + if ($module == 'ctools' && $plugin == 'export_ui') { + return 'plugins/' . $plugin; + } +} + +/** + * Implementation of hook_panels_dashboard_blocks(). + * + * Adds page information to the Panels dashboard. + */ +function stylizer_panels_dashboard_blocks(&$vars) { + $vars['links']['stylizer'] = array( + 'title' => l(t('Custom style'), 'admin/build/stylizer/add'), + 'description' => t('Custom styles can be applied to Panel regions and Panel panes.'), + ); + + // Load all mini panels and their displays. + ctools_include('export'); + ctools_include('stylizer'); + $items = ctools_export_crud_load_all('stylizer'); + $count = 0; + $rows = array(); + + $base_types = ctools_get_style_base_types(); + foreach ($items as $item) { + $style = ctools_get_style_base($item->settings['style_base']); + if ($style && $style['module'] == 'panels') { + $type = $base_types[$style['module']][$style['type']]['title']; + + $rows[] = array( + check_plain($item->admin_title), + $type, + array( + 'data' => l(t('Edit'), "admin/build/stylizer/list/$item->name/edit"), + 'class' => 'links', + ), + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + } + + if ($rows) { + $content = theme('table', array(), $rows, array('class' => 'panels-manage')); + } + else { + $content = '<p>' . t('There are no custom styles.') . '</p>'; + } + + $vars['blocks']['stylizer'] = array( + 'title' => t('Manage styles'), + 'link' => l(t('Go to list'), 'admin/build/stylizer'), + 'content' => $content, + 'class' => 'dashboard-styles', + 'section' => 'left', + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_block_legacy.png b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_block_legacy.png new file mode 100644 index 0000000000000000000000000000000000000000..f2e07474a358847696d4525c1e94696fd1907559 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_block_legacy.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_page.png b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_page.png new file mode 100644 index 0000000000000000000000000000000000000000..27efe7c13a4ba5eb9c8c98d1610c71408a77abae Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_page.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_page_legacy.png b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_page_legacy.png new file mode 100644 index 0000000000000000000000000000000000000000..31173353471a442a55937d9ca37db8861c953777 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/icon_views_page_legacy.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views.inc new file mode 100644 index 0000000000000000000000000000000000000000..d9277d4b3ac92500f38f76a7298c4f2c776c5778 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views.inc @@ -0,0 +1,565 @@ +<?php + +/** + * @file + * Content type plugin to expose all views as content. + */ + +if (variable_get('ctools_content_all_views', TRUE)) { + $plugin = array( + 'title' => t('All views'), + 'defaults' => array( + 'override_pager_settings' => FALSE, + 'use_pager' => FALSE, + 'nodes_per_page' => 10, + 'pager_id' => 0, + 'offset' => 0, + 'more_link' => FALSE, + 'feed_icons' => FALSE, + 'panel_args' => FALSE, + 'link_to_view' => FALSE, + 'args' => '', + 'url' => '', + ), + 'add form' => array( + 'views_content_views_select_display' => t('Select display'), + 'views_content_views_content_type_edit_form' => array( + 'default' => TRUE, // put wrapper here, not on the previous form. + 'title' => t('Configure view'), + ), + ), + 'all contexts' => TRUE, + ); +} + +/** + * Return all content types available. + */ +function views_content_views_content_type_content_types($plugin) { + $types = array(); + // It can be fairly intensive to calculate this, so let's cache this in the + // cache_views table. The nice thing there is that if views ever change, that + // table will always be cleared. Except for the occasional default view, so + // we must use the Views caching functions in order to respect Views caching + // settings. + views_include('cache'); + $data = views_cache_get('views_content_all', TRUE); + if (!empty($data->data)) { + $types = $data->data; + } + + if (empty($types)) { + $views = views_get_all_views(); + + foreach ($views as $view) { + if (empty($view->disabled)) { + $types[$view->name] = _views_content_views_content_type($view); + } + } + + views_cache_set('views_content_all', $types, TRUE); + } + + return $types; +} + +/** + * Return a single content type. + */ +function views_content_views_content_type_content_type($subtype, $plugin) { + $view = views_get_view($name); + if (empty($view)) { + return; + } + + return _views_content_views_content_type($view); +} + +/** + * Create the content type info array to give back to ctools for a given display. + */ +function _views_content_views_content_type($view) { + $title = $view->name; + + $icon = 'icon_views_page_legacy.png'; + + return array( + 'view' => $view->name, + 'title' => $title, + 'icon' => $icon, + 'description' => filter_xss_admin($view->description), + 'category' => t('Views'), + ); + +} + +/** + * Output function for the 'views' content type. + * + * Outputs a view based on the module and delta supplied in the configuration. + */ +function views_content_views_content_type_render($subtype, $conf, $panel_args, $contexts) { + if (!is_array($contexts)) { + $contexts = array($contexts); + } + + $view = _views_content_views_update_conf($conf, $subtype); + + if (empty($view) || !is_object($view) || empty($view->display_handler)) { + return; + } + + if (!$view->display_handler->access($GLOBALS['user'])) { + return; + } + + $arguments = explode('/', $_GET['q']); + $args = $conf['args']; + + foreach ($arguments as $id => $arg) { + $args = str_replace("%$id", $arg, $args); + } + + foreach ($panel_args as $id => $arg) { + if (is_string($arg)) { + $args = str_replace("@$id", $arg, $args); + } + } + + $args = preg_replace(',/?(%\d|@\d),', '', $args); + $args = $args ? explode('/', $args) : array(); + + if ($conf['panel_args'] && is_array($panel_args)) { + $args = array_merge($panel_args, $args); + } + + if (isset($conf['context']) && is_array($conf['context'])) { + foreach ($conf['context'] as $count => $context_info) { + if (!strpos($context_info, '.')) { + // old skool: support pre-converter contexts as well. + $cid = $context_info; + $converter = ''; + } + else { + list($cid, $converter) = explode('.', $context_info, 2); + } + if (!empty($contexts[$cid])) { + $arg = ctools_context_convert_context($contexts[$cid], $converter); + array_splice($args, $count, 0, array($arg)); + } + } + } + + $view->set_arguments($args); + + if ($conf['url']) { + $view->override_path = $conf['url']; + } + + $block = new stdClass(); + $block->module = 'views'; + $block->delta = $view->name .'-'. $view->current_display; + + if (!empty($conf['link_to_view'])) { + $block->title_link = $view->get_url(); + } + + if (!empty($conf['more_link'])) { + $block->more = array('href' => $view->get_url()); + $view->display_handler->set_option('use_more', FALSE); + } + + // Only set use_pager if they differ, this way we can avoid overwriting the + // pager type that Views uses. + if ($conf['override_pager_settings']) { + if (method_exists($view, 'init_pager')) { + // Views 3 version + $view->set_items_per_page($conf['nodes_per_page']); + $view->set_offset($conf['offset']); + + $pager = $view->display_handler->get_option('pager'); + if ($conf['use_pager'] && ($pager['type'] == 'none' || $pager['type'] == 'some')) { + $pager['type'] = 'full'; + } + elseif (!$conf['use_pager'] && $pager['type'] != 'none' && $pager['type'] != 'some') { + $pager['type'] = $view->get_items_per_page() ? 'some' : 'none'; + } + + if ($conf['use_pager']) { + if (!isset($pager['options']['id']) || $pager['options']['id'] != $conf['pager_id']) { + $pager['options']['id'] = $conf['pager_id']; + } + } + + $view->display_handler->set_option('pager', $pager); + } + else { + if (!$view->display_handler->get_option('use_pager') || empty($conf['use_pager'])) { + $view->display_handler->set_option('use_pager', $conf['use_pager']); + } + $view->display_handler->set_option('pager_element', $conf['pager_id']); + $view->display_handler->set_option('items_per_page', $conf['nodes_per_page']); + $view->display_handler->set_option('offset', $conf['offset']); + } + } + + $stored_feeds = drupal_add_feed(); + $block->content = $view->preview(); + $block->title = $view->get_title(); + + if (empty($view->result) && !$view->display_handler->get_option('empty') && empty($view->style_plugin->definition['even empty'])) { + return; + } + + if (!empty($conf['feed_icons'])) { + $new_feeds = drupal_add_feed(); + if ($diff = array_diff(array_keys($new_feeds), array_keys($stored_feeds))) { + foreach ($diff as $url) { + $block->feeds[$url] = $new_feeds[$url]; + } + } + } + + $view->destroy(); + return $block; +} + +/** + * Returns an edit form for a block. + */ +function views_content_views_select_display(&$form, &$form_state) { + $view = views_get_view($form_state['subtype_name']); + if (empty($view)) { + return; + } + + $displays = array(); + foreach ($view->display as $id => $display) { + // Content pane views should never be used this way. + if ($display->display_plugin != 'panel_pane') { + $displays[$id] = $display->display_title; + } + } + + $form['display'] = array( + '#type' => 'select', + '#title' => t('Display'), + '#options' => $displays, + '#description' => t('Choose which display of this view you wish to use.') + ); +} + +/** + * Submit the basic view edit form. + * + * This just dumps everything into the $conf array. + */ +function views_content_views_select_display_submit(&$form, &$form_state) { + $form_state['conf']['display'] = $form_state['values']['display']; +} + +/** + * Returns an edit form for a block. + */ +function views_content_views_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + $view = _views_content_views_update_conf($conf, $form_state['subtype_name']); + + if (empty($view) || !is_object($view)) { + $form['markup'] = array('#value' => t('Broken/missing/deleted view.')); + return; + } + + $form_state['title'] = t('Configure view @view (@display)', array('@view' => $view->name, '@display' => $view->display[$conf['display']]->display_title)); + + // @todo + // If using the older format, just a context is listed. We should go through + // and check for that and forcibly set them to the right converter so that + // it doesn't get changed to some whacky default. Oooor just let it get changed + // to 'no context', I suppose. + + $required = array(); + if (isset($view->display_handler) && $arguments = $view->display_handler->get_handlers('argument')) { + foreach ($arguments as $arg) { + $required[] = new ctools_context_optional($arg->ui_name(), 'any'); + } + } + + if ($required) { + $form['context'] = ctools_context_converter_selector($form_state['contexts'], $required, isset($conf['context']) ? $conf['context'] : array()); + } + + $form['link_to_view'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['link_to_view'], + '#title' => t('Link title to view'), + ); + + $form['more_link'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['more_link'], + '#title' => t('Provide a "more" link that links to the view'), + '#description' => t('This is independent of any more link that may be provided by the view itself; if you see two more links, turn this one off. Views will only provide a more link if using the "block" type, however, so if using embed, use this one.'), + ); + + $form['feed_icons'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['feed_icons'], + '#title' => t('Display feed icons'), + ); + + $form['pager_settings'] = array( + '#type' => 'fieldset', + '#collapsible' => FALSE, + '#title' => t('Custom pager settings'), + ); + + $form['pager_settings']['override_pager_settings'] = array( + '#type' => 'checkbox', + '#title' => t('Use different pager settings from view settings'), + '#default_value' => $conf['override_pager_settings'], + '#id' => 'override-pager-checkbox', + ); + + if ($view->display_handler->get_option('use_ajax')) { + $form['pager_settings']['warning'] = array( + '#value' => '<div>' . t('<strong>Warning: </strong> This view has AJAX enabled. Overriding the pager settings will work initially, but when the view is updated via AJAX, the original settings will be used. You should not override pager settings on Views with the AJAX setting enabled.') . '</div>', + ); + } + + $form['pager_settings']['use_pager'] = array( + '#prefix' => '<div class="container-inline">', + '#type' => 'checkbox', + '#title' => t('Use pager'), + '#default_value' => $conf['use_pager'], + '#id' => 'use-pager-checkbox', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('override-pager-checkbox' => array(1)), + ); + $form['pager_settings']['pager_id'] = array( + '#type' => 'textfield', + '#default_value' => $conf['pager_id'], + '#title' => t('Pager ID'), + '#size' => 4, + '#id' => 'use-pager-textfield', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('override-pager-checkbox' => array(1), 'use-pager-checkbox' => array(1)), + '#dependency_count' => 2, + '#suffix' => '</div>', + ); + + $form['pager_settings']['nodes_per_page'] = array( + '#type' => 'textfield', + '#default_value' => $conf['nodes_per_page'], + '#size' => 4, + '#title' => t('Num posts'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('override-pager-checkbox' => array(1)), + ); + + $form['pager_settings']['offset'] = array( + '#type' => 'textfield', + '#default_value' => $conf['offset'], + '#title' => t('Offset'), + '#size' => 4, + '#description' => t('The number of items to skip and not display.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('override-pager-checkbox' => array(1)), + ); + + $form['panel_args'] = array( + '#type' => 'checkbox', + '#title' => t('Send arguments'), + '#default_value' => $conf['panel_args'], + '#description' => t('Select this to send all arguments from the panel directly to the view. If checked, the panel arguments will come after any context arguments above and precede any additional arguments passed in through the Arguments field below. Note that arguments do not include the base URL; only values after the URL or set as placeholders are considered arguments.'), + ); + + $form['args'] = array( + '#type' => 'textfield', + '#default_value' => $conf['args'], + '#title' => t('Arguments'), + '#size' => 30, + '#description' => t('Additional arguments to send to the view as if they were part of the URL in the form of arg1/arg2/arg3. You may use %0, %1, ..., %N to grab arguments from the URL. Or use @0, @1, @2, ..., @N to use arguments passed into the panel. Note: use these values only as a last resort. In future versions of Panels these may go away.'), + ); + + $form['url'] = array( + '#type' => 'textfield', + '#default_value' => $conf['url'], + '#title' => t('Override URL'), + '#size' => 30, + '#description' => t('If this is set, override the View URL; this can sometimes be useful to set to the panel URL'), + ); + + $view->destroy(); + return $form; +} + +/** + * Store form values in $conf. + */ +function views_content_views_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_content_type_admin_title($subtype, $conf) { + $view = _views_content_views_update_conf($conf, $subtype); + + if (!is_object($view)) { + return t('Deleted/missing view @view', array('@view' => $view)); + } + + $title = $view->display[$view->current_display]->display_title; + return t('View: @name', array('@name' => $view->name . '-' . $title)); +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_content_type_admin_info($subtype, $conf, $contexts) { + $view = _views_content_views_update_conf($conf, $subtype); + + if (!is_object($view)) { + return t('Deleted/missing view @view', array('@view' => $view)); + } + + $display = empty($conf['display']) ? $view->current_display : $conf['display']; + $block = new stdClass(); + $block->title = t('View information'); + + $block->content = '<ul>'; + $block->content .= '<li>' . t('Using display @display.', array('@display' => $view->display[$display]->display_title)) . '</li>'; + + if (!empty($conf['context']) && $arguments = $view->display_handler->get_handlers('argument')) { + $argument = reset($arguments); + foreach ($conf['context'] as $count => $context_info) { + if (!$argument) { + break; + } + + if (!strpos($context_info, '.')) { + // old skool: support pre-converter contexts as well. + $cid = $context_info; + $converter = ''; + } + else { + list($cid, $converter) = explode('.', $context_info, 2); + } + + if (!empty($contexts[$cid])) { + $converters = ctools_context_get_converters($cid . '.', $contexts[$cid]); + $converter = !empty($converters[$context_info]) ? $converters[$context_info] : t('Default'); + $block->content .= '<li>' . t('Argument @arg using context @context converted into @converter', array( + '@arg' => $argument->ui_name(), '@context' => $contexts[$cid]->get_identifier(), + '@converter' => $converter)) . '</li>'; + } + $argument = next($arguments); + } + } + + $block->content .= '<li>' . t('@count items displayed.', array('@count' => $conf['nodes_per_page'])) . '</li>'; + if ($conf['use_pager']) { + $block->content .= '<li>' . t('With pager.') . '</li>'; + } + else { + $block->content .= '<li>' . t('Without pager.') . '</li>'; + } + + if ($conf['offset']) { + $block->content .= '<li>' . t('Skipping first @count results', array('@count' => $conf['offset'])) . '</li>'; + } + if ($conf['more_link']) { + $block->content .= '<li>' . t('With more link.') . '</li>'; + } + if ($conf['feed_icons']) { + $block->content .= '<li>' . t('With feed icon.') . '</li>'; + } + if ($conf['panel_args']) { + $block->content .= '<li>' . t('Sending arguments.') . '</li>'; + } + if ($conf['args']) { + $block->content .= '<li>' . t('Using arguments: @args', array('@args' => $conf['args'])) . '</li>'; + } + if ($conf['url']) { + $block->content .= '<li>' . t('Using url: @url', array('@url' => $conf['url'])) . '</li>'; + } + + $view->destroy(); + return $block; +} + +/** + * Update the $conf to deal with updates from Drupal 5. + * + * @param &$conf + * The $conf array to modify. + * @param $subtype + * The subtype in use. This should just be the view name, but in older + * versions it was the view name with a dash and the display ID. + * If this is the case, we can use it to correct the 'display' setting + * in the $conf. + * @return + * The $view with the initialized display. If the $view could not be + * loaded, the name attempted will be loaded for use in errors. + * Correct error checking on this function checks against is_object(). + */ +function _views_content_views_update_conf(&$conf, $subtype) { + $plugin = ctools_get_content_type('views'); + + // Special: Existing content types get a different default than new ones: + if (!empty($conf) && !isset($conf['override_pager_settings'])) { + $conf['override_pager_settings'] = TRUE; + } + + // Make sure that our defaults are always set if there is no + // previous setting. This helps updates go more smoothly. + foreach ($plugin['defaults'] as $key => $value) { + if (!isset($conf[$key])) { + $conf[$key] = $value; + } + } + + if (strpos($subtype, '-')) { + list($name, $display) = explode('-', $subtype); + $view = views_get_view($name); + if (!isset($conf['display'])) { + $conf['display'] = $display; + } + } + else { + $name = $subtype; + $view = views_get_view($subtype); + $display = isset($conf['display']) ? $conf['display'] : 'default'; + } + + if (empty($view)) { + return $name; + } + + $view->set_display($display); + // $view->current_display will now reflect this value. + + // If set NOT to override, go ahead and refresh from the view. + if (empty($conf['override_pager_settings'])) { + if (method_exists($view, 'init_pager')) { + $pager = $view->display_handler->get_option('pager'); + $conf['use_pager'] = $pager['type'] != 'none' && $pager['type'] != 'some'; + $conf['pager_id'] = isset($pager['options']['id']) ? $pager['options']['id'] : 0; + $conf['offset'] = isset($pager['options']['offset']) ? $pager['options']['offset'] : 0; + $conf['nodes_per_page'] = isset($pager['options']['items_per_page']) ? $pager['options']['items_per_page'] : 0; + } + else { + $conf['use_pager'] = $view->display_handler->get_option('use_pager'); + $conf['pager_id'] = $view->display_handler->get_option('element_id'); + $conf['nodes_per_page'] = $view->display_handler->get_option('items_per_page'); + $conf['offset'] = $view->display_handler->get_option('offset'); + } + } + + return $view; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_attachments.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_attachments.inc new file mode 100644 index 0000000000000000000000000000000000000000..a9cb0fb560767df93b27e15057a5557840e0d503 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_attachments.inc @@ -0,0 +1,73 @@ +<?php + +/** + * @file + * Allow a view context to display its attachment(s). + */ + +$plugin = array( + 'title' => t('View attachment'), + 'category' => t('View context'), + 'icon' => 'icon_views_page.png', + 'description' => t('Display the attachments on a view context.'), + 'required context' => new ctools_context_required(t('View'), 'view'), + 'defaults' => array( + 'which' => array(), + ), +); + +/** + * Render the node_terms content type. + */ +function views_content_views_attachments_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'views_attachments'; + $block->delta = $context->argument; + $block->title = ''; + $block->content = ''; + + $output = views_content_context_get_output($context); + foreach ($conf['which'] as $attachment) { + if (isset($output[$attachment])) { + $block->content .= $output[$attachment]; + } + } + + return $block; +} + + +function views_content_views_attachments_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + + $form['which'] = array( + '#type' => 'checkboxes', + '#options' => array( + 'attachment_before' => t('"Before" attachment'), + 'attachment_after' => t('"After" attachment'), + ), + '#default_value' => $conf['which'], + ); +} + +function views_content_views_attachments_content_type_edit_form_validate(&$form, &$form_state) { + if (!array_filter($form_state['values']['which'])) { + form_error($form['which'], t('You must select at least one attachment to display.')); + } +} + +function views_content_views_attachments_content_type_edit_form_submit(&$form, &$form_state) { + $form_state['conf']['which'] = array_filter($form_state['values']['which']); +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_attachments_content_type_admin_title($subtype, $conf, $context) { + return t('"@context" attachment', array('@context' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_empty.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_empty.inc new file mode 100644 index 0000000000000000000000000000000000000000..9b35ebfbebf26d455b1271be4c54f78ee1c574c3 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_empty.inc @@ -0,0 +1,54 @@ +<?php + +/** + * @file + * Allow a view context to display its attachment(s). + */ + +$plugin = array( + 'title' => t('View empty text'), + 'category' => t('View context'), + 'icon' => 'icon_views_page.png', + 'description' => t('Display the view empty text if there are no results.'), + 'required context' => new ctools_context_required(t('View'), 'view'), + 'defaults' => array( + 'which' => array(), + ), +); + +/** + * Render the node_terms content type. + */ +function views_content_views_empty_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'views_empty'; + $block->delta = $context->argument; + $block->title = ''; + $block->content = ''; + + $output = views_content_context_get_output($context); + if (isset($output['empty'])) { + $block->content = $output['empty']; + } + + return $block; +} + +function views_content_views_empty_content_type_edit_form(&$form, &$form_state) { +} + +function views_content_views_empty_content_type_edit_form_submit(&$form, &$form_state) { + // Kept so we guarantee we have a submit handler. +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_empty_content_type_admin_title($subtype, $conf, $context) { + return t('"@context" empty text', array('@context' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_exposed.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_exposed.inc new file mode 100644 index 0000000000000000000000000000000000000000..2119d55167c1d2ab2b316793be4c61ff1aa00e70 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_exposed.inc @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * Allow a view context to display its attachment(s). + */ + +$plugin = array( + 'title' => t('View exposed widgets'), + 'category' => t('View context'), + 'icon' => 'icon_views_page.png', + 'description' => t('Display the view exposed widgets if there are no results.'), + 'required context' => new ctools_context_required(t('View'), 'view'), + 'defaults' => array( + 'which' => array(), + ), +); + +/** + * Render the node_terms content type. + */ +function views_content_views_exposed_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'views_exposed'; + $block->delta = $context->argument; + $block->title = ''; + $block->content = ''; + + $output = views_content_context_get_output($context); + $block->content = $output['exposed']; + + return $block; +} + +function views_content_views_exposed_content_type_edit_form(&$form, &$form_state) { +} + +function views_content_views_exposed_content_type_edit_form_submit(&$form, &$form_state) { + // Kept so we guarantee we have a submit handler. +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_exposed_content_type_admin_title($subtype, $conf, $context) { + return t('"@context" exposed widgets', array('@context' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_feed.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_feed.inc new file mode 100644 index 0000000000000000000000000000000000000000..e9e2899025bf268ca7f3bc6a71e5915bf304d7c9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_feed.inc @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * Allow a view context to display its attachment(s). + */ + +$plugin = array( + 'title' => t('View feed icon'), + 'category' => t('View context'), + 'icon' => 'icon_views_page.png', + 'description' => t('Display the view feed icon if there are no results.'), + 'required context' => new ctools_context_required(t('View'), 'view'), + 'defaults' => array( + 'which' => array(), + ), +); + +/** + * Render the node_terms content type. + */ +function views_content_views_feed_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'views_feed'; + $block->delta = $context->argument; + $block->title = ''; + $block->content = ''; + + $output = views_content_context_get_output($context); + $block->content = $output['feed_icon']; + + return $block; +} + +function views_content_views_feed_content_type_edit_form(&$form, &$form_state) { +} + +function views_content_views_feed_content_type_edit_form_submit(&$form, &$form_state) { + // Kept so we guarantee we have a submit handler. +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_feed_content_type_admin_title($subtype, $conf, $context) { + return t('"@context" feed icon', array('@context' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_footer.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_footer.inc new file mode 100644 index 0000000000000000000000000000000000000000..cf8619e1c9f42c0bcc2cfc1ce3e30e3aa448e041 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_footer.inc @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * Allow a view context to display its attachment(s). + */ + +$plugin = array( + 'title' => t('View footer'), + 'category' => t('View context'), + 'icon' => 'icon_views_page.png', + 'description' => t('Display the view footer if there are no results.'), + 'required context' => new ctools_context_required(t('View'), 'view'), + 'defaults' => array( + 'which' => array(), + ), +); + +/** + * Render the node_terms content type. + */ +function views_content_views_footer_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'views_footer'; + $block->delta = $context->argument; + $block->title = ''; + $block->content = ''; + + $output = views_content_context_get_output($context); + $block->content = $output['footer']; + + return $block; +} + +function views_content_views_footer_content_type_edit_form(&$form, &$form_state) { +} + +function views_content_views_footer_content_type_edit_form_submit(&$form, &$form_state) { + // Kept so we guarantee we have a submit handler. +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_footer_content_type_admin_title($subtype, $conf, $context) { + return t('"@context" footer', array('@context' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_header.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_header.inc new file mode 100644 index 0000000000000000000000000000000000000000..3c3310dea413625c4c09c373948efb77e73d78b7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_header.inc @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * Allow a view context to display its attachment(s). + */ + +$plugin = array( + 'title' => t('View header'), + 'category' => t('View context'), + 'icon' => 'icon_views_page.png', + 'description' => t('Display the view header if there are no results.'), + 'required context' => new ctools_context_required(t('View'), 'view'), + 'defaults' => array( + 'which' => array(), + ), +); + +/** + * Render the node_terms content type. + */ +function views_content_views_header_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'views_header'; + $block->delta = $context->argument; + $block->title = ''; + $block->content = ''; + + $output = views_content_context_get_output($context); + $block->content = $output['header']; + + return $block; +} + +function views_content_views_header_content_type_edit_form(&$form, &$form_state) { +} + +function views_content_views_header_content_type_edit_form_submit(&$form, &$form_state) { + // Kept so we guarantee we have a submit handler. +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_header_content_type_admin_title($subtype, $conf, $context) { + return t('"@context" header', array('@context' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_pager.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_pager.inc new file mode 100644 index 0000000000000000000000000000000000000000..ec7c0c5f29cc85e6665009b3e56dc7a9bbc2592c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_pager.inc @@ -0,0 +1,52 @@ +<?php + +/** + * @file + * Allow a view context to display its attachment(s). + */ + +$plugin = array( + 'title' => t('View pager'), + 'category' => t('View context'), + 'icon' => 'icon_views_page.png', + 'description' => t('Display the view pager if there are no results.'), + 'required context' => new ctools_context_required(t('View'), 'view'), + 'defaults' => array( + 'which' => array(), + ), +); + +/** + * Render the node_terms content type. + */ +function views_content_views_pager_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'views_pager'; + $block->delta = $context->argument; + $block->title = ''; + $block->content = ''; + + $output = views_content_context_get_output($context); + $block->content = $output['pager']; + + return $block; +} + +function views_content_views_pager_content_type_edit_form(&$form, &$form_state) { +} + +function views_content_views_pager_content_type_edit_form_submit(&$form, &$form_state) { + // Kept so we guarantee we have a submit handler. +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_pager_content_type_admin_title($subtype, $conf, $context) { + return t('"@context" pager', array('@context' => $context->identifier)); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_panes.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_panes.inc new file mode 100644 index 0000000000000000000000000000000000000000..95b384337800ba29cd3480fcd6580f83d1a56122 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_panes.inc @@ -0,0 +1,612 @@ +<?php + +/** + * @file + * Content type plugin to allow Views to be exposed as a display type, + * leaving most of the configuration on the view. + */ + +/** + * Implementation of hook_ctools_content_types() + */ +function views_content_views_panes_ctools_content_types() { + return array( + 'title' => t('View panes'), + 'admin settings' => 'views_content_admin_form', + 'js' => array(drupal_get_path('module', 'ctools') . '/js/dependent.js'), + ); +} + +/** + * Return all content types available. + */ +function views_content_views_panes_content_type_content_types($plugin) { + $types = array(); + // It can be fairly intensive to calculate this, so let's cache this in the + // cache_views table. The nice thing there is that if views ever change, that + // table will always be cleared. Except for the occasional default view, so + // we must use the Views caching functions in order to respect Views caching + // settings. + views_include('cache'); + $data = views_cache_get('views_content_panes', TRUE); + if (!empty($data->data)) { + $types = $data->data; + } + + if (empty($types)) { + $types = array(); + + $views = views_get_all_views(); + + foreach ($views as $view) { + if (!empty($view->disabled)) { + continue; + } + + $view->init_display(); + + foreach ($view->display as $id => $display) { + if (empty($display->handler->panel_pane_display)) { + continue; + } + $info = _views_content_panes_content_type($view, $display); + if ($info) { + $types[$view->name . '-' . $id] = $info; + } + } + + $view->destroy(); + } + views_cache_set('views_content_panes', $types, TRUE); + } + + return $types; +} + +/** + * Return a single content type. + */ +function views_content_views_panes_content_type_content_type($subtype, $plugin) { + list($name, $display) = explode('-', $subtype); + $view = views_get_view($name); + if (empty($view)) { + return; + } + + $view->set_display($display); + $retval = _views_content_panes_content_type($view, $view->display[$display]); + + $view->destroy(); + return $retval; +} + +function _views_content_panes_content_type($view, $display) { + // Ensure the handler is the right type, as Views will fall back to + // the default display if something is broken: + if (get_class($display->handler) != 'views_content_plugin_display_panel_pane') { + return; + } + + $title = $display->handler->get_option('pane_title'); + if (!$title) { + $title = $view->name; + } + + $description = $display->handler->get_option('pane_description'); + if (!$description) { + $description = $view->description; + } + + $category = $display->handler->get_option('pane_category'); + if (!$category['name']) { + $category['name'] = t('View panes'); + } + + $icon = 'icon_views_page.png'; + + $contexts = array(); + + $arguments = $display->handler->get_argument_input(); + foreach ($arguments as $argument) { + if ($argument['type'] == 'context') { + if (strpos($argument['context'], '.')) { + list($context, $converter) = explode('.', $argument['context'], 2); + } + else { + // Backwards-compat for before we had a system for delimiting the data + // we retrieve out of context objects. + $context = $argument['context']; + } + $class = 'ctools_context_' . (empty($argument['context_optional']) ? 'required' : 'optional'); + $contexts[] = new $class($argument['label'], $context); + } + } + + $allow = $display->handler->get_option('allow'); + return array( + 'title' => $title, + 'icon' => $icon, + 'description' => filter_xss_admin($description), + 'required context' => $contexts, + 'category' => array($category['name'], $category['weight']), + 'no title override' => empty($allow['title_override']), + ); +} + +/** + * Output function for the 'views' content type. + * + * Outputs a view based on the module and delta supplied in the configuration. + */ +function views_content_views_panes_content_type_render($subtype, $conf, $panel_args, $contexts) { + if (!is_array($contexts)) { + $contexts = array($contexts); + } + + list($name, $display) = explode('-', $subtype); + $view = views_get_view($name); + if (empty($view)) { + return; + } + + $view->set_display($display); + if (!$view->display_handler->access($GLOBALS['user']) || !$view->display_handler->panel_pane_display) { + return; + } + + $view->display_handler->set_pane_conf($conf); + + $args = array(); + $arguments = $view->display_handler->get_option('arguments'); + + + $context_keys = array_keys($contexts); + foreach ($view->display_handler->get_argument_input() as $id => $argument) { + switch ($argument['type']) { + case 'context': + $key = array_shift($context_keys); + if (isset($contexts [$key])) { + if (strpos($argument['context'], '.')) { + list($context, $converter) = explode('.', $argument['context'], 2); + $args[] = ctools_context_convert_context($contexts[$key], $converter); + } + else { + $args[] = $contexts[$key]->argument; + } + } + break; + + case 'fixed': + $args[] = $argument['fixed']; + break; + + case 'panel': + $args[] = isset($panel_args[$argument['panel']]) ? $panel_args[$argument['panel']] : NULL; + break; + + case 'user': + $args[] = (isset($conf['arguments'][$id]) && $conf['arguments'][$id] !== '') ? $conf['arguments'][$id] : NULL; + break; + + case 'wildcard': + // Put in the wildcard. + $args[] = isset($arguments[$id]['wildcard']) ? $arguments[$id]['wildcard'] : '*'; + break; + + case 'none': + default: + // Put in NULL. + // views.module knows what to do with NULL (or missing) arguments + $args[] = NULL; + break; + } + } + + // remove any trailing NULL arguments as these are non-args: + while (count($args) && end($args) === NULL) { + array_pop($args); + } + $view->set_arguments($args); + + $allow = $view->display_handler->get_option('allow'); + + if (!empty($conf['path'])) { + $conf['path'] = ctools_context_keyword_substitute($conf['path'], array(), $contexts); + } + if ($allow['path_override'] && !empty($conf['path'])) { + $view->override_path = $conf['path']; + } + else if ($path = $view->display_handler->get_option('inherit_panels_path')) { + $view->override_path = $_GET['q']; + } + + $block = new stdClass(); + $block->module = 'views'; + $block->delta = $view->name . $display; + + if (($allow['link_to_view'] && !empty($conf['link_to_view'])) || + (!$allow['link_to_view'] && $view->display_handler->get_option('link_to_view'))) { + $block->title_link = $view->get_url(); + } + + // more link + if ($allow['more_link']) { + if (empty($conf['more_link'])) { + $view->display_handler->set_option('use_more', FALSE); + } + else { + $view->display_handler->set_option('use_more', TRUE); + // make sure the view runs the count query so we know whether or not the + // more link applies. + $view->get_total_rows = TRUE; + } + } + + if ($allow['items_per_page'] && isset($conf['items_per_page'])) { + $view->display_handler->set_option('items_per_page', $conf['items_per_page']); + // And here too, which works in Views 3 where the above does not. + $view->set_items_per_page($conf['items_per_page']); + } + + if ($allow['offset']) { + $view->display_handler->set_option('offset', $conf['offset']); + $view->set_offset($conf['offset']); + } + + if ($allow['use_pager']) { + // Only set use_pager if they differ, this way we can avoid overwriting the + // pager type that Views uses. + // Views 3 version + if (method_exists($view, 'init_pager')) { + $pager = $view->display_handler->get_option('pager'); + if ($conf['use_pager'] && ($pager['type'] == 'none' || $pager['type'] == 'some')) { + $pager['type'] = 'full'; + } + elseif (!$conf['use_pager'] && $pager['type'] != 'none' && $pager['type'] != 'some') { + $pager['type'] = $view->get_items_per_page() || !empty($pager['options']['items_per_page']) ? 'some' : 'none'; + } + + if ($conf['use_pager']) { + if (!isset($pager['options']['id']) || $pager['options']['id'] != $conf['pager_id']) { + $pager['options']['id'] = $conf['pager_id']; + } + } + + $view->display_handler->set_option('pager', $pager); + } + else { + if (!$view->display_handler->get_option('use_pager') || empty($conf['use_pager'])) { + $view->display_handler->set_option('use_pager', $conf['use_pager']); + } + + $view->display_handler->set_option('pager_element', $conf['pager_id']); + } + } + + if ($allow['fields_override']) { + if ($conf['fields_override']) { + $fields = $view->get_items('field'); + foreach ($fields as $field => $display) { + $fields[$field]['exclude'] = empty($conf['fields_override'][$field]); + } + $view->display_handler->set_option('fields', $fields); + + } + } + + if ($allow['exposed_form'] && !empty($conf['exposed'])) { + $view->set_exposed_input($conf['exposed']); + } + + $stored_feeds = drupal_add_feed(); + + $block->content = $view->preview(); + if (empty($view->result) && !$view->display_handler->get_option('empty') && empty($view->style_plugin->definition['even empty'])) { + return; + } + + $block->title = $view->get_title(); + + if (empty($view->total_rows) || $view->total_rows <= $view->display_handler->get_option('items_per_page')) { + unset($block->more); + } + + if ((!empty($allow['feed_icons']) && !empty($conf['feed_icons'])) || + (empty($allow['feed_icons']) && $view->display_handler->get_option('feed_icons'))) { + $new_feeds = drupal_add_feed(); + if ($diff = array_diff(array_keys($new_feeds), array_keys($stored_feeds))) { + foreach ($diff as $url) { + $block->feeds[$url] = $new_feeds[$url]; + } + } + } + + return $block; +} + +/** + * Returns an edit form for a block. + */ +function views_content_views_panes_content_type_edit_form(&$form, &$form_state) { + $conf = $form_state['conf']; + $contexts = $form_state['contexts']; + // This allows older content to continue to work, where we used to embed + // the display directly. + list($name, $display_id) = explode('-', $form_state['subtype_name']); + $view = views_get_view($name); + + if (empty($view)) { + $form['markup'] = array('#value' => t('Broken/missing/deleted view.')); + return; + } + + $view->set_display($display_id); + + $allow = $view->display_handler->get_option('allow'); + + // Provide defaults for everything in order to prevent warnings. + if (empty($conf)) { + $conf['link_to_view'] = $view->display_handler->get_option('link_to_view'); + $conf['more_link'] = $view->display_handler->get_option('more_link'); + $conf['feed_icons'] = FALSE; + $conf['use_pager'] = $view->display_handler->get_option('use_pager'); + $conf['pager_id'] = $view->display_handler->get_option('element_id'); + $conf['items_per_page'] = $view->display_handler->get_option('items_per_page'); + $conf['offset'] = $view->display_handler->get_option('offset'); + $conf['path_override'] = FALSE; + $conf['path'] = $view->get_path(); + $conf['fields_override'] = $view->display_handler->get_option('fields_override'); + } + + $form['arguments']['#tree'] = TRUE; + + foreach ($view->display_handler->get_argument_input() as $id => $argument) { + if ($argument['type'] == 'user') { + $form['arguments'][$id] = array( + '#type' => 'textfield', + '#default_value' => isset($conf['arguments'][$id]) ? $conf['arguments'][$id] : '', + '#title' => $argument['label'], + ); + } + } + if ($allow['link_to_view'] ) { + $form['link_to_view'] = array( + '#type' => 'checkbox', + '#default_value' => isset($conf['link_to_view']) ? $conf['link_to_view'] : $view->display_handler->get_option('link_to_view'), + '#title' => t('Link title to page'), + ); + } + if ($allow['more_link']) { + $form['more_link'] = array( + '#type' => 'checkbox', + '#default_value' => isset($conf['more_link']) ? $conf['more_link'] : $view->display_handler->get_option('use_more'), + '#description' => t('The text of this link will be "@more". This setting can only be modified on the View configuration.', array('@more' => $view->display_handler->use_more_text())), + '#title' => t('Provide a "more" link.'), + ); + } + + if (!empty($allow['feed_icons'])) { + $form['feed_icons'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($conf['feed_icons']), + '#title' => t('Display feed icons'), + ); + } + + $view->init_style(); + if ($allow['fields_override'] && $view->style_plugin->uses_fields()) { + $form['fields_override'] = array( + '#type' => 'fieldset', + '#title' => 'Fields to display', + '#collapsible' => TRUE, + '#tree' => TRUE, + ); + foreach ($view->display_handler->get_handlers('field') as $field => $handler) { + $title = $handler->ui_name(); + if ($handler->options['label']) { + $title .= ' ('. $handler->options['label'] .')'; + } + + $form['fields_override'][$field] = array( + '#type' => 'checkbox', + '#title' => $title, + '#default_value' => isset($conf['fields_override'][$field]) ? $conf['fields_override'][$field] : TRUE, + ); + } + } + + ctools_include('dependent'); + if ($allow['use_pager']) { + $form['use_pager'] = array( + '#type' => 'checkbox', + '#title' => t('Use pager'), + '#default_value' => isset($conf['use_pager']) ? $conf['use_pager'] : $view->display_handler->get_option('use_pager'), + '#id' => 'use-pager-checkbox', + '#prefix' => '<div class="container-inline">', + ); + $form['pager_id'] = array( + '#type' => 'textfield', + '#default_value' => isset($conf['pager_id']) ? $conf['pager_id'] : $view->display_handler->get_option('element_id'), + '#title' => t('Pager ID'), + '#size' => 4, + '#id' => 'use-pager-textfield', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('use-pager-checkbox' => array(1)), + '#suffix' => '</div>', + ); + } + if ($allow['items_per_page']) { + $form['items_per_page'] = array( + '#type' => 'textfield', + '#default_value' => isset($conf['items_per_page']) ? $conf['items_per_page'] : $view->display_handler->get_option('items_per_page'), + '#title' => t('Num items'), + '#size' => 4, + '#description' => t('Select the number of items to display, or 0 to display all results.'), + ); + } + if ($allow['offset']) { + $form['offset'] = array( + '#type' => 'textfield', + '#default_value' => isset($conf['offset']) ? $conf['offset'] : $view->display_handler->get_option('offset'), + '#title' => t('Offset'), + '#size' => 4, + '#description' => t('Enter the number of items to skip; enter 0 to skip no items.'), + ); + } + if ($allow['path_override']) { + $form['path'] = array( + '#type' => 'textfield', + '#default_value' => isset($conf['path']) ? $conf['path'] : $view->get_path(), + '#title' => t('Override path'), + '#size' => 30, + '#description' => t('If this is set, override the View URL path; this can sometimes be useful to set to the panel URL.'), + ); + if (!empty($contexts)) { + $form['path']['#description'] .= ' ' . t('You may use substitutions in this path.'); + + // Add js for collapsible fieldsets manually + drupal_add_js('misc/collapse.js'); + + // We have to create a manual fieldset because fieldsets do not support IDs. + // Use 'hidden' instead of 'markup' so that the process will run. + $form['contexts_prefix'] = array( + '#type' => 'hidden', + '#id' => 'edit-path-substitutions', + '#prefix' => '<div><fieldset id="edit-path-substitutions" class="collapsed collapsible"><legend>' . t('Substitutions') . '</legend>', + ); + + $rows = array(); + foreach ($contexts as $context) { + foreach (ctools_context_get_converters('%' . check_plain($context->keyword) . ':', $context) as $keyword => $title) { + $rows[] = array( + check_plain($keyword), + t('@identifier: @title', array('@title' => $title, '@identifier' => $context->identifier)), + ); + } + } + + $header = array(t('Keyword'), t('Value')); + $form['contexts']['context'] = array('#value' => theme('table', $header, $rows)); + $form['contexts_suffix'] = array( + '#value' => '</fieldset></div>', + ); + } + } + + if (empty($conf['exposed'])) { + $conf['exposed'] = array(); + } + + if ($allow['exposed_form']) { + // If the exposed form is part of pane configuration, get the exposed + // form re-tool it for our use. + $exposed_form_state = array( + 'view' => &$view, + 'display' => &$view->display[$display_id], + ); + + $view->set_exposed_input($conf['exposed']); + + if (version_compare(views_api_version(), '3', '>=')) { + $exposed_form_state['exposed_form_plugin'] = $view->display_handler->get_plugin('exposed_form'); + } + $view->init_handlers(); + $exposed_form = views_exposed_form($exposed_form_state); + + $form['exposed'] = array( + '#tree' => TRUE, + ); + + foreach ($exposed_form['#info'] as $id => $info) { + $form['exposed'][$id] = array( + '#type' => 'item', + '#id' => 'views-exposed-pane', + ); + + if (!empty($info['label'])) { + $form['exposed'][$id]['#title'] = $info['label']; + } + + if (!empty($info['operator']) && !empty($exposed_form[$info['operator']])) { + $form['exposed'][$id][$info['operator']] = $exposed_form[$info['operator']]; + $form['exposed'][$id][$info['operator']]['#parents'] = array('exposed', $info['operator']); + $form['exposed'][$id][$info['operator']]['#default_value'] = isset($conf['exposed'][$info['operator']]) ? $conf['exposed'][$info['operator']] : ''; + } + $form['exposed'][$id][$info['value']] = $exposed_form[$info['value']]; + $form['exposed'][$id][$info['value']]['#parents'] = array('exposed', $info['value']); + $form['exposed'][$id][$info['value']]['#default_value'] = isset($conf['exposed'][$info['value']]) ? $conf['exposed'][$info['value']] : ''; + } + } +} + +/** + * Store form values in $conf. + */ +function views_content_views_panes_content_type_edit_form_submit(&$form, &$form_state) { + // Copy everything from our defaults. + $keys = array('link_to_view', 'more_link', 'feed_icons', 'use_pager', + 'pager_id', 'items_per_page', 'offset', 'path_override', 'path', 'arguments', 'fields_override', 'exposed'); + + foreach ($keys as $key) { + if (isset($form_state['values'][$key])) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } + } +} + + +/** + * Returns the administrative title for a type. + */ +function views_content_views_panes_content_type_admin_title($subtype, $conf, $contexts) { + list($name, $display) = explode('-', $subtype); + $view = views_get_view($name); + if (empty($view) || empty($view->display[$display])) { + return t('Deleted/missing view @view', array('@view' => $name)); + } + + $view->set_display($display); + $title = $view->display_handler->get_option('pane_title'); + return check_plain($title ? $title : $view->name); +} + +/** + * Returns the administrative title for a type. + */ +function views_content_views_panes_content_type_admin_info($subtype, $conf, $contexts) { + $info = array(); + + list($view_name, $display_name) = explode('-', $subtype); + $view = views_get_view($view_name); + + if (empty($view) || empty($view->display[$display_name])) { + return; + } + + $view->set_display($display_name); + + // Add arguments first + if (!empty($conf['arguments'])) { + $keys = array_keys($conf['arguments']); + $values = array_values($conf['arguments']); + $argument_input = $view->display_handler->get_option('argument_input'); + + foreach ($conf['arguments'] as $key => $value) { + $label = $argument_input[$key]['label']; + $info[] = $label .': '. $value; + } + } + + $block = new stdClass; + if ($info) { + $block->title = array_shift($info); + + $info[] = $view->display_handler->get_option('pane_description'); + $block->content = theme('item_list', $info); + } + else { + $block->title = $view->display_handler->get_option('pane_description'); + $block->content = ''; + } + return $block; +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_row.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_row.inc new file mode 100644 index 0000000000000000000000000000000000000000..bc48c648c7a7b14fe0147a87b8ac8c158063b8d4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/content_types/views_row.inc @@ -0,0 +1,183 @@ +<?php + +/** + * @file + * Allow a view context to display individual rows. + */ + +$plugin = array( + 'title' => t('View row'), + 'category' => t('View context'), + 'icon' => 'icon_views_page.png', + 'description' => t('Display one or more rows from a loaded view context.'), + 'required context' => new ctools_context_required(t('View'), 'view'), + 'defaults' => array( + 'rows' => array(), + 'use_fields' => array(), + 'fields' => array(), + ), + 'add form' => array( + 'views_content_views_row_content_type_edit_form' => t('Select context'), + 'views_content_views_row_edit' => t('Configure rows'), + ), + 'edit form' => array( + 'views_content_views_row_content_type_edit_form' => t('Select context'), + 'views_content_views_row_edit' => t('Configure rows'), + ), +); + +/** + * Render the node_terms content type. + */ +function views_content_views_row_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Build the content type block. + $block = new stdClass(); + $block->module = 'views_row'; + $block->delta = $context->argument; + $block->title = ''; + $block->content = ''; + + // This guarantees the view is rendered normally which must happen. + $view = views_content_context_get_view($context); + $output = views_content_context_get_output($context); + if (empty($conf['use_fields']) || empty($view->style_plugin->row_plugin)) { + foreach ($conf['rows'] as $row) { + // We store the row number 1-indexed but they are 0-indexed internally. + $block->content .= $output['rows'][$row - 1]; + } + } + else { + // If we're using specific fields, go through and poke the 'exclude' flag. + foreach ($view->field as $id => $field) { + $view->field[$id]->options['exclude'] = empty($conf['fields'][$id]); + } + + // Rerender just the rows we need. + foreach ($conf['rows'] as $row) { + $view->row_index = $row - 1; + if (!empty($view->result[$row - 1])) { + $block->content .= $view->style_plugin->row_plugin->render($view->result[$row - 1]); + } + } + } + + return $block; +} + +function views_content_views_row_content_type_edit_form(&$form, &$form_state) { + // This form does nothing; it exists to let the main form select the view context. +} + +function views_content_views_row_content_type_edit_form_submit(&$form, &$form_state) { + +} + +function views_content_views_row_edit(&$form, &$form_state) { + $conf = $form_state['conf']; + + if (empty($form_state['contexts'][$conf['context']])) { + $form['markup'] = array('#value' => '<p>' . t('Invalid context selected.') . '</p>'); + return; + } + + $view = views_content_context_get_view($form_state['contexts'][$conf['context']]); + if (empty($view)) { + $form['markup'] = array('#value' => '<p>' . t('Context contains an invalid view.') . '</p>'); + return; + } + + $rows = $view->get_items_per_page(); + + if (empty($rows)) { + $form['markup'] = array('#value' => '<p>' . t('The view must have a maximum number of items set to use this content type.') . '</p>'); + return; + } + + foreach (range(1, $rows) as $row) { + $options[$row] = t('Row @number', array('@number' => $row)); + } + + $form['rows'] = array( + '#type' => 'checkboxes', + '#title' => t('Display'), + '#options' => $options, + '#default_value' => $conf['rows'], + ); + + if ($view->display_handler->uses_fields()) { + $form['use_fields'] = array( + '#type' => 'checkbox', + '#title' => t('Display specific fields'), + '#default_value' => $conf['use_fields'], + ); + + ctools_include('dependent'); + $form['fields'] = array( + '#type' => 'checkboxes', + '#options' => $view->display_handler->get_field_labels(), + '#default_value' => $conf['fields'], + '#prefix' => '<div id="edit-fields-wrapper"><div id="edit-fields">', + '#suffix' => '</div></div>', + '#process' => array('ctools_dependent_process', 'expand_checkboxes'), + '#dependency' => array('edit-use-fields' => array(TRUE)), + ); + } +} + +function views_content_views_row_edit_validate(&$form, &$form_state) { + if (!array_filter($form_state['values']['rows'])) { + form_error($form['rows'], t('You must select at least one row to display.')); + } +} + +function views_content_views_row_edit_submit(&$form, &$form_state) { + $form_state['conf']['rows'] = array_filter($form_state['values']['rows']); + $form_state['conf']['use_fields'] = $form_state['values']['use_fields']; + $form_state['conf']['fields'] = array_filter($form_state['values']['fields']); +} + +function views_content_views_row_content_type_admin_info($subtype, $conf, $contexts) { + $context = $contexts[$conf['context']]; + $block->title = t('Row information'); + + if (!empty($conf['use_fields'])) { + $display_fields = array(); + $view = views_content_context_get_view($context); + if (empty($view)) { + $block->title = t('Broken view'); + return $block; + } + $fields = $view->display_handler->get_field_labels(); + + foreach ($conf['fields'] as $field) { + if (!empty($fields[$field])) { + $display_fields[$field] = '"<em>' . check_plain($fields[$field]) . '</em>"'; + } + } + + if ($display_fields) { + $block->content = t('Displaying: !fields', array('!fields' => implode(', ', $display_fields))); + } + else { + $block->content = t('Displaying no fields due to misconfiguration.'); + } + } + else { + $block->content = t('Displaying the configured row.'); + } + + return $block; +} + +function views_content_views_row_content_type_admin_title($subtype, $conf, $context) { + $rows = array_filter($conf['rows']); + return format_plural(count($rows), + '"@context" row @rows', + '"@context" rows @rows', + array('@context' => $context->identifier, '@rows' => implode(', ', $rows)) + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/contexts/view.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/contexts/view.inc new file mode 100644 index 0000000000000000000000000000000000000000..08ee466f45042637faf62ea6d0edfe6413ff334d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/contexts/view.inc @@ -0,0 +1,133 @@ +<?php + +/** + * @file + * + * Plugin to provide a node context. A node context is a node wrapped in a + * context object that can be utilized by anything that accepts contexts. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("View"), + 'description' => t('Loads a view result into a context that can then be displayed across a panel or turned into other contexts.'), + 'context' => 'views_content_context_view_create', + + 'settings form' => 'views_content_context_view_settings_form', + 'settings form validate' => 'views_content_context_view_settings_form_validate', + 'settings form submit' => 'views_content_context_view_settings_form_submit', + + 'defaults' => array('view' => ''), + + 'keyword' => 'view', + 'context name' => 'view', + + /* + 'convert list' => 'views_content_context_view_convert_list', + 'convert' => 'views_content_context_view_convert', + */ + + /* + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the node ID of a node for this context.'), + ), + */ +); + +function views_content_context_view_create($empty, $data = NULL, $conf = FALSE) { + $context = new ctools_context('view'); + $context->plugin = 'view'; + + if ($empty) { + return $context; + } + + if ($conf) { + if (is_array($data) && !empty($data['view'])) { + list($name, $display_id) = explode(':', $data['view'], 2); + $data = views_get_view($name); + if ($data) { + $data->set_display($display_id); + } + } + } + + if (is_object($data)) { + // We don't store the loaded view as we don't want the view object + // cached. + $context->data = array( + 'name' => $data->name, + 'display' => $data->current_display, + ); + + // At runtime, this can get populated. Once it is populated this + // object should not be cached. + $context->view = NULL; + $context->title = $data->get_title(); + $context->argument = $data->name . ':' . $data->current_display; + + $context->restrictions['base'] = array($data->base_table); + + return $context; + } +} + +function views_content_context_view_settings_form($conf) { + $views = views_get_applicable_views('returns context'); + foreach ($views as $data) { + list($view, $id) = $data; + $title = $view->display_handler->get_option('admin_title'); + if (!$title) { + $title = $view->name; + } + $options[$view->name . ':' . $id] = $title; + } + + if (!empty($options)) { + natcasesort($options); + $form['view'] = array( + '#type' => 'select', + '#options' => $options, + '#title' => t('View'), + ); + } + else { + $form['view'] = array( + '#value' => '<p>' . t('There are currently no views with Context displays enabled. You should go to the view administration and add a Context display to use a view as a context.') . '</p>', + ); + } + + return $form; +} + +/** + * Validate a node. + */ +function views_content_context_view_settings_form_validate($form, &$form_values, &$form_state) { + if (empty($form_values['view'])) { + form_error($form['view'], t('You must select a view.')); + } +} + +/** + * Provide a list of ways that this context can be converted to a string. + */ +function views_content_context_view_convert_list() { + $list = array( + ); + + return $list; +} + +/** + * Convert a context into a string. + */ +function views_content_context_view_convert($context, $type) { + switch ($type) { + } +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/node_from_view.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/node_from_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..71bdbacfef836a3bc1bd1850715c96b33693c30d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/node_from_view.inc @@ -0,0 +1,63 @@ +<?php + +/** + * @file + * Plugin to provide an relationship handler for node from view. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Node from view'), + 'keyword' => 'node', + 'description' => t('Extract a node context from a view context of the base type node.'), + 'required context' => new ctools_context_required(t('View'), 'view', array('base' => 'node')), + 'context' => 'views_content_node_from_view_context', + 'settings form' => 'views_content_node_from_view_settings_form', + 'settings form validate' => 'views_content_node_from_view_settings_form_validate', + 'defaults' => array('row' => 1), +); + +/** + * Return a new context based on an existing context. + */ +function views_content_node_from_view_context($context, $conf, $placeholder = FALSE) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data) || $placeholder) { + return ctools_context_create_empty('node', NULL); + } + $view = views_content_context_get_view($context); + // Ensure the view executes, but we don't need its output. + views_content_context_get_output($context); + + $row = intval($conf['row']) - 1; + if (isset($view->result[$row])) { + $nid = $view->result[$row]->{$view->base_field}; + if ($nid) { + $node = node_load($nid); + return ctools_context_create('node', $node); + } + } + return ctools_context_create_empty('node', NULL); +} + +/** + * Settings form for the relationship. + */ +function views_content_node_from_view_settings_form($conf) { + $form['row'] = array( + '#title' => t('Row number'), + '#type' => 'textfield', + '#default_value' => $conf['row'], + ); + + return $form; +} + +function views_content_node_from_view_settings_form_validate($form, &$form_values, &$form_state) { + if (intval($form_values['row']) <= 0) { + form_error($form['row'], t('Row number must be a positive integer value.')); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/term_from_view.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/term_from_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..8f534fde1f0e182f2f4a55decaa5060861c1d03e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/term_from_view.inc @@ -0,0 +1,63 @@ +<?php + +/** + * @file + * Plugin to provide an relationship handler for term from view. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Term from view'), + 'keyword' => 'term', + 'description' => t('Extract a term context from a view context of the base type term.'), + 'required context' => new ctools_context_required(t('View'), 'view', array('base' => 'term_data')), + 'context' => 'views_content_term_from_view_context', + 'settings form' => 'views_content_term_from_view_settings_form', + 'settings form validate' => 'views_content_term_from_view_settings_form_validate', + 'defaults' => array('row' => 1), +); + +/** + * Return a new context based on an existing context. + */ +function views_content_term_from_view_context($context, $conf, $placeholder = FALSE) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data) || $placeholder) { + return ctools_context_create_empty('term', NULL); + } + $view = views_content_context_get_view($context); + // Ensure the view executes, but we don't need its output. + views_content_context_get_output($context); + + $row = intval($conf['row']) - 1; + if (isset($view->result[$row])) { + $tid = $view->result[$row]->{$view->base_field}; + if ($tid) { + $term = taxonomy_get_term($tid); + return ctools_context_create('term', $term); + } + } + return ctools_context_create_empty('term', NULL); +} + +/** + * Settings form for the relationship. + */ +function views_content_term_from_view_settings_form($conf) { + $form['row'] = array( + '#title' => t('Row number'), + '#type' => 'textfield', + '#default_value' => $conf['row'], + ); + + return $form; +} + +function views_content_term_from_view_settings_form_validate($form, &$form_values, &$form_state) { + if (intval($form_values['row']) <= 0) { + form_error($form['row'], t('Row number must be a positive integer value.')); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/user_from_view.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/user_from_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..79d97dbf1265fb53ddf26724f05aa43b5cb7fd42 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/relationships/user_from_view.inc @@ -0,0 +1,63 @@ +<?php + +/** + * @file + * Plugin to provide an relationship handler for user from term. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('User from view'), + 'keyword' => 'user', + 'description' => t('Extract a user context from a view context of the base type user.'), + 'required context' => new ctools_context_required(t('View'), 'view', array('base' => 'users')), + 'context' => 'views_content_user_from_view_context', + 'settings form' => 'views_content_user_from_view_settings_form', + 'settings form validate' => 'views_content_user_from_view_settings_form_validate', + 'defaults' => array('row' => 1), +); + +/** + * Return a new context based on an existing context. + */ +function views_content_user_from_view_context($context, $conf, $placeholder = FALSE) { + // If unset it wants a generic, unfilled context, which is just NULL. + if (empty($context->data) || $placeholder) { + return ctools_context_create_empty('user', NULL); + } + $view = views_content_context_get_view($context); + // Ensure the view executes, but we don't need its output. + views_content_context_get_output($context); + + $row = intval($conf['row']) - 1; + if (isset($view->result[$row])) { + $uid = $view->result[$row]->{$view->base_field}; + if ($uid) { + $user = user_load($uid); + return ctools_context_create('user', $user); + } + } + return ctools_context_create_empty('user', NULL); +} + +/** + * Settings form for the relationship. + */ +function views_content_user_from_view_settings_form($conf) { + $form['row'] = array( + '#title' => t('Row number'), + '#type' => 'textfield', + '#default_value' => $conf['row'], + ); + + return $form; +} + +function views_content_user_from_view_settings_form_validate($form, &$form_values, &$form_state) { + if (intval($form_values['row']) <= 0) { + form_error($form['row'], t('Row number must be a positive integer value.')); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content.views.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..629c28c737c2e92b276ce5eec416222b3445a53e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content.views.inc @@ -0,0 +1,60 @@ +<?php + +/** + * @file + * Contains Views plugin definitions for the panel pane display. + */ + +/** + * Implementation of hook_views_plugins + */ +function views_content_views_plugins() { + return array( + 'display' => array( + 'panel_pane' => array( + 'title' => t('Content pane'), + 'help' => t('Is available as content for a panel or dashboard display.'), + 'handler' => 'views_content_plugin_display_panel_pane', + 'path' => drupal_get_path('module', 'views_content') . '/plugins/views', + 'theme path' => drupal_get_path('module', 'views') . '/theme', + 'theme' => 'views_view', + 'use ajax' => TRUE, + 'use pager' => TRUE, + 'use more' => TRUE, + 'accept attachments' => TRUE, + 'help topic' => 'display-pane', + 'admin' => t('Content pane'), + ), + 'ctools_context' => array( + 'title' => t('Context'), + 'help' => t('Makes the view results available as a context for use in Panels and other applications.'), + 'handler' => 'views_content_plugin_display_ctools_context', + 'path' => drupal_get_path('module', 'views_content') . '/plugins/views', + 'theme path' => drupal_get_path('module', 'views') . '/theme', + 'theme' => 'views_view', + 'use ajax' => FALSE, + 'use pager' => TRUE, + 'use more' => FALSE, + 'accept attachments' => TRUE, + 'returns context' => TRUE, + 'help topic' => 'display-context', + 'admin' => t('Context'), + ), + ), + 'style' => array( + 'ctools_context' => array( + 'title' => t('Context'), + 'help' => t('Contains rows in contexts.'), + 'handler' => 'views_content_plugin_style_ctools_context', + 'path' => drupal_get_path('module', 'views_content') . '/plugins/views', + 'theme path' => drupal_get_path('module', 'views') . '/theme', + 'theme' => 'views_view_unformatted', + 'uses row plugin' => TRUE, + 'uses fields' => TRUE, + 'uses options' => TRUE, + 'type' => 'context', + 'help topic' => 'style-context', + ), + ), + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_display_ctools_context.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_display_ctools_context.inc new file mode 100644 index 0000000000000000000000000000000000000000..d0131496191de13f65005cf22815a76805f32800 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_display_ctools_context.inc @@ -0,0 +1,155 @@ +<?php +/** + * @file + * Contains the block display plugin. + */ + +/** + * The plugin that handles a block. + * + * @ingroup views_display_plugins + */ +class views_content_plugin_display_ctools_context extends views_plugin_display { + function get_style_type() { return 'context'; } + + function defaultable_sections($section = NULL) { + if (in_array($section, array('style_options', 'style_plugin', 'row_options', 'row_plugin',))) { + return FALSE; + } + + return parent::defaultable_sections($section); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['admin_title'] = array('default' => '', 'translatable' => TRUE); + + // Overrides for standard stuff: + $options['style_plugin']['default'] = 'ctools_context'; + $options['row_plugin']['default'] = 'fields'; + $options['defaults']['default']['style_plugin'] = FALSE; + $options['defaults']['default']['style_options'] = FALSE; + $options['defaults']['default']['row_plugin'] = FALSE; + $options['defaults']['default']['row_options'] = FALSE; + + return $options; + } + + /** + * The display block handler returns the structure necessary for a block. + */ + function execute() { + $this->executing = TRUE; + return $this->view->render(); + } + + function preview() { + $this->previewing = TRUE; + return $this->view->render(); + } + + /** + * Render this display. + */ + function render() { + if (!empty($this->previewing)) { + return theme($this->theme_functions(), $this->view); + } + else { + // We want to process the view like we're theming it, but not actually + // use the template part. Therefore we run through all the preprocess + // functions which will populate the variables array. + $hooks = theme_get_registry(); + $info = $hooks[$this->definition['theme']]; + if (!empty($info['file'])) { + @include_once('./' . $info['path'] . '/' . $info['file']); + } + $this->variables = array('view' => &$this->view); + + if (isset($info['preprocess functions']) && is_array($info['preprocess functions'])) { + foreach ($info['preprocess functions'] as $preprocess_function) { + if (function_exists($preprocess_function)) { + $preprocess_function($this->variables, $this->definition['theme']); + } + } + } + } + + return $this->variables; + } + + /** + * Provide the summary for page options in the views UI. + * + * This output is returned as an array. + */ + function options_summary(&$categories, &$options) { + // It is very important to call the parent function here: + parent::options_summary($categories, $options); + + $categories['context'] = array( + 'title' => t('Context settings'), + ); + + $admin_title = $this->get_option('admin_title'); + if (empty($admin_title)) { + $admin_title = t('Use view name'); + } + + if (strlen($admin_title) > 16) { + $admin_title = substr($admin_title, 0, 16) . '...'; + } + + $options['admin_title'] = array( + 'category' => 'context', + 'title' => t('Admin title'), + 'value' => $admin_title, + ); + + } + + /** + * Provide the default form for setting options. + */ + function options_form($form, &$form_state) { + // It is very important to call the parent function here: + parent::options_form($form, $form_state); + switch ($form_state['section']) { + case 'row_plugin': + // This just overwrites the existing row_plugin which is using the wrong options. + $form['row_plugin']['#options'] = views_fetch_plugin_names('row', 'normal', array($this->view->base_table)); + break; + case 'admin_title': + $form['#title'] .= t('Administrative title'); + + $form['admin_title'] = array( + '#type' => 'textfield', + '#default_value' => $this->get_option('admin_title'), + '#description' => t('This is the title that will appear for this view context in the configure context dialog. If left blank, the view name will be used.'), + ); + break; + } + } + + /** + * Perform any necessary changes to the form values prior to storage. + * There is no need for this function to actually store the data. + */ + function options_submit(&$form, &$form_state) { + // It is very important to call the parent function here: + parent::options_submit($form, $form_state); + switch ($form_state['section']) { + case 'admin_title': + $this->set_option($form_state['section'], $form_state['values'][$form_state['section']]); + break; + } + } + + /** + * Block views use exposed widgets only if AJAX is set. + */ + function uses_exposed() { + return FALSE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_display_panel_pane.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_display_panel_pane.inc new file mode 100644 index 0000000000000000000000000000000000000000..7d08130751014fb51540357fe34a655c20235c43 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_display_panel_pane.inc @@ -0,0 +1,403 @@ +<?php + +/** + * The plugin that handles a panel_pane. + */ +class views_content_plugin_display_panel_pane extends views_plugin_display { + /** + * If this variable is true, this display counts as a panel pane. We use + * this variable so that other modules can create alternate pane displays. + */ + var $panel_pane_display = TRUE; + var $has_pane_conf = NULL; + + function option_definition() { + $options = parent::option_definition(); + + $options['pane_title'] = array('default' => '', 'translatable' => TRUE); + $options['pane_description'] = array('default' => '', 'translatable' => TRUE); + $options['pane_category'] = array( + 'contains' => array( + 'name' => array('default' => 'View panes', 'translatable' => TRUE), + 'weight' => array('default' => 0), + ), + ); + + $options['allow'] = array( + 'contains' => array( + 'use_pager' => array('default' => FALSE), + 'items_per_page' => array('default' => FALSE), + 'offset' => array('default' => FALSE), + 'link_to_view' => array('default' => FALSE), + 'more_link' => array('default' => FALSE), + 'path_override' => array('default' => FALSE), + 'title_override' => array('default' => FALSE), + 'exposed_form' => array('default' => FALSE), + 'fields_override' => array('default' => FALSE), + ), + ); + + $options['argument_input'] = array('default' => array()); + $options['link_to_view'] = array('default' => 0); + $options['inherit_panels_path'] = array('default' => 0); + + return $options; + } + + function has_pane_conf() { + return isset($this->has_pane_conf); + } + + function set_pane_conf($conf = array()) { + $this->set_option('pane_conf', $conf); + $this->has_pane_conf = TRUE; + } + + /** + * Provide the summary for page options in the views UI. + * + * This output is returned as an array. + */ + function options_summary(&$categories, &$options) { + // It is very important to call the parent function here: + parent::options_summary($categories, $options); + + $categories['panel_pane'] = array( + 'title' => t('Pane settings'), + ); + + $pane_title = $this->get_option('pane_title'); + if (empty($pane_title)) { + $pane_title = t('Use view name'); + } + + if (strlen($pane_title) > 16) { + $pane_title = substr($pane_title, 0, 16) . '...'; + } + + $options['pane_title'] = array( + 'category' => 'panel_pane', + 'title' => t('Admin title'), + 'value' => $pane_title, + ); + + $pane_description = $this->get_option('pane_description'); + if (empty($pane_description)) { + $pane_description = t('Use view description'); + } + + if (strlen($pane_description) > 16) { + $pane_description = substr($pane_description, 0, 16) . '...'; + } + + $options['pane_description'] = array( + 'category' => 'panel_pane', + 'title' => t('Admin desc'), + 'value' => $pane_description, + ); + + $category = $this->get_option('pane_category'); + $pane_category = $category['name']; + if (empty($pane_category)) { + $pane_category = t('View panes'); + } + + if (strlen($pane_category) > 16) { + $pane_category = substr($pane_category, 0, 16) . '...'; + } + + $options['pane_category'] = array( + 'category' => 'panel_pane', + 'title' => t('Category'), + 'value' => $pane_category, + ); + + $options['link_to_view'] = array( + 'category' => 'panel_pane', + 'title' => t('Link to view'), + 'value' => $this->get_option('link_to_view') ? t('Yes') : t('No'), + ); + + $options['inherit_panels_path'] = array( + 'category' => 'panel_pane', + 'title' => t('Use Panel path'), + 'value' => $this->get_option('inherit_panels_path') ? t('Yes') : t('No'), + ); + + $options['argument_input'] = array( + 'category' => 'panel_pane', + 'title' => t('Argument input'), + 'value' => t('Edit'), + ); + + $allow = $this->get_option('allow'); + $filtered_allow = array_filter($allow); + + $options['allow'] = array( + 'category' => 'panel_pane', + 'title' => t('Allow settings'), + 'value' => empty($filtered_allow) ? t('None') : ($allow === $filtered_allow ? t('All') : t('Some')), + ); + } + + /** + * Provide the default form for setting options. + */ + function options_form(&$form, &$form_state) { + // It is very important to call the parent function here: + parent::options_form($form, $form_state); + + switch ($form_state['section']) { + case 'allow': + $form['#title'] .= t('Allow settings'); + $form['description'] = array( + '#value' => '<div class="form-item description">' . t('Checked settings will be available in the panel pane config dialog for modification by the panels user. Unchecked settings will not be available and will only use the settings in this display.') . '</div>', + ); + + $options = array( + 'use_pager' => t('Use pager'), + 'items_per_page' => t('Items per page'), + 'offset' => t('Pager offset'), + 'link_to_view' => t('Link to view'), + 'more_link' => t('More link'), + 'path_override' => t('Path override'), + 'title_override' => t('Title override'), + 'exposed_form' => t('Use exposed widgets form as pane configuration'), + 'fields_override' => t('Fields override'), + ); + + $allow = array_filter($this->get_option('allow')); + $form['allow'] = array( + '#type' => 'checkboxes', + '#default_value' => $allow, + '#options' => $options, + ); + break; + case 'pane_title': + $form['#title'] .= t('Administrative title'); + + $form['pane_title'] = array( + '#type' => 'textfield', + '#default_value' => $this->get_option('pane_title'), + '#description' => t('This is the title that will appear for this view pane in the add content dialog. If left blank, the view name will be used.'), + ); + break; + + case 'pane_description': + $form['#title'] .= t('Administrative description'); + + $form['pane_description'] = array( + '#type' => 'textfield', + '#default_value' => $this->get_option('pane_description'), + '#description' => t('This is text that will be displayed when the user mouses over the pane in the add content dialog. If blank the view description will be used.'), + ); + break; + + case 'pane_category': + $form['#title'] .= t('Administrative description'); + + $cat = $this->get_option('pane_category'); + $form['pane_category']['#tree'] = TRUE; + $form['pane_category']['name'] = array( + '#type' => 'textfield', + '#default_value' => $cat['name'], + '#description' => t('This is category the pane will appear in on the add content dialog.'), + ); + $form['pane_category']['weight'] = array( + '#title' => t('Weight'), + '#type' => 'textfield', + '#default_value' => $cat['weight'], + '#description' => t('This is the default weight of the category. Note that if the weight of a category is defined in multiple places, only the first one Panels sees will get that definition, so if the weight does not appear to be working, check other places that the weight might be set.'), + ); + break; + + case 'link_to_view': + $form['#title'] .= t('Link pane title to view'); + + $form['link_to_view'] = array( + '#type' => 'select', + '#options' => array(1 => t('Yes'), 0 => t('No')), + '#default_value' => $this->get_option('link_to_view'), + ); + break; + + case 'inherit_panels_path': + $form['#title'] .= t('Inherit path from panel display'); + + $form['inherit_panels_path'] = array( + '#type' => 'select', + '#options' => array(1 => t('Yes'), 0 => t('No')), + '#default_value' => $this->get_option('inherit_panels_path'), + '#description' => t('If yes, all links generated by Views, such as more links, summary links, and exposed input links will go to the panels display path, not the view, if the display has a path.'), + ); + break; + + case 'argument_input': + $form['#title'] .= t('Choose the data source for view arguments'); + $argument_input = $this->get_argument_input(); + + ctools_include('context'); + $form['argument_input']['#tree'] = TRUE; + + foreach ($argument_input as $id => $argument) { + $form['argument_input'][$id] = array( + '#tree' => TRUE, + ); + + $safe = str_replace(array('][', '_', ' '), '-', $id); + $type_id = 'edit-argument-input-' . $safe; + + $form['argument_input'][$id]['type'] = array( + '#type' => 'select', + '#options' => array( + 'none' => t('No argument'), + 'wildcard' => t('Argument wildcard'), + 'context' => t('From context'), + 'panel' => t('From panel argument'), + 'fixed' => t('Fixed'), + 'user' => t('Input on pane config'), + ), + '#id' => $type_id, + '#title' => t('@arg source', array('@arg' => $argument['name'])), + '#default_value' => $argument['type'], + ); + + $form['argument_input'][$id]['context'] = array( + '#type' => 'select', + '#title' => t('Required context'), + '#description' => t('If "From context" is selected, which type of context to use.'), + '#default_value' => $argument['context'], + '#options' => ctools_context_get_all_converters(), + '#process' => array('views_process_dependency'), + '#dependency' => array($type_id => array('context')), + ); + + $form['argument_input'][$id]['context_optional'] = array( + '#type' => 'checkbox', + '#title' => t('Context is optional'), + '#description' => t('This context need not be present for the pane to function. If you plan to use this, ensure that the argument handler can handle empty values gracefully.'), + '#default_value' => $argument['context_optional'], + '#process' => array('views_process_dependency'), + '#dependency' => array($type_id => array('context')), + ); + + $form['argument_input'][$id]['panel'] = array( + '#type' => 'select', + '#title' => t('Panel argument'), + '#description' => t('If "From panel argument" is selected, which panel argument to use.'), + '#default_value' => $argument['panel'], + '#options' => array(0 => t('First'), 1 => t('Second'), 2 => t('Third'), 3 => t('Fourth'), 4 => t('Fifth'), 5 => t('Sixth')), + '#process' => array('views_process_dependency'), + '#dependency' => array($type_id => array('panel')), + ); + + $form['argument_input'][$id]['fixed'] = array( + '#type' => 'textfield', + '#title' => t('Fixed argument'), + '#description' => t('If "Fixed" is selected, what to use as an argument.'), + '#default_value' => $argument['fixed'], + '#process' => array('views_process_dependency'), + '#dependency' => array($type_id => array('fixed')), + ); + + $form['argument_input'][$id]['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#description' => t('If this argument is presented to the panels user, what label to apply to it.'), + '#default_value' => empty($argument['label']) ? $argument['name'] : $argument['label'], + '#process' => array('views_process_dependency'), + '#dependency' => array($type_id => array('user')), + ); + } + break; + } + } + + /** + * Perform any necessary changes to the form values prior to storage. + * There is no need for this function to actually store the data. + */ + function options_submit($form, &$form_state) { + // It is very important to call the parent function here: + parent::options_submit($form, $form_state); + switch ($form_state['section']) { + case 'allow': + case 'argument_input': + case 'link_to_view': + case 'inherit_panels_path': + case 'pane_title': + case 'pane_description': + case 'pane_category': + $this->set_option($form_state['section'], $form_state['values'][$form_state['section']]); + break; + } + } + + /** + * Adjust the array of argument input to match the current list of + * arguments available for this display. This ensures that changing + * the arguments doesn't cause the argument input field to just + * break. + */ + function get_argument_input() { + $arguments = $this->get_option('argument_input'); + $handlers = $this->get_handlers('argument'); + + // We use a separate output so as to seamlessly discard info for + // arguments that no longer exist. + $output = array(); + + foreach ($handlers as $id => $handler) { + if (empty($arguments[$id])) { + $output[$id] = array( + 'type' => 'none', + 'context' => 'any', + 'context_optional' => FALSE, + 'panel' => 0, + 'fixed' => '', + 'name' => $handler->ui_name(), + ); + } + else { + $output[$id] = $arguments[$id]; + $output[$id]['name'] = $handler->ui_name(); + } + } + + return $output; + } + + function use_more() { + $allow = $this->get_option('allow'); + if (!$allow['more_link'] || !$this->has_pane_conf()) { + return parent::use_more(); + } + $conf = $this->get_option('pane_conf'); + return (bool) $conf['more_link']; + } + + function get_path() { + if (empty($this->view->override_path)) { + return parent::get_path(); + } + return $this->view->override_path; + } + + /** + * Determine if this display should display the exposed + * filters widgets, so the view will know whether or not + * to render them. + * + * Regardless of what this function + * returns, exposed filters will not be used nor + * displayed unless uses_exposed() returns TRUE. + */ + function displays_exposed() { + $conf = $this->get_option('allow'); + // If this is set, the exposed form is part of pane configuration, not + // rendered normally. + return empty($conf['exposed_form']); + } + +} + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_style_ctools_context.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_style_ctools_context.inc new file mode 100644 index 0000000000000000000000000000000000000000..513de3ce561124a22f4b672b732840756faec249 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/plugins/views/views_content_plugin_style_ctools_context.inc @@ -0,0 +1,46 @@ +<?php +/** + * @file + * Contains the default style plugin. + */ + +/** + * Default style plugin to render rows one after another with no + * decorations. + * + * @ingroup views_style_plugins + */ +class views_content_plugin_style_ctools_context extends views_plugin_style { + var $rows = array(); + + /** + * Render the display in this style. + */ + function render() { + if (!empty($this->view->display_handler->previewing)) { + return parent::render(); + } + + $this->rows = array(); + if ($this->uses_row_plugin() && empty($this->row_plugin)) { + vpr('views_plugin_style_default: Missing row plugin'); + return; + } + + // Group the rows according to the grouping field, if specified. + $sets = $this->render_grouping($this->view->result, $this->options['grouping']); + + // Render each group separately and concatenate. Plugins may override this + // method if they wish some other way of handling grouping. + $output = ''; + foreach ($sets as $title => $records) { + foreach ($records as $row_index => $row) { + $this->view->row_index = $row_index; + $this->rows[$row_index] = $this->row_plugin->render($row); + } + } + unset($this->view->row_index); + return $this->rows; + } + +} diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/views_content.admin.inc b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/views_content.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/views_content.info b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/views_content.info new file mode 100644 index 0000000000000000000000000000000000000000..98dd8a8e64d1105f50607725ea6cfdd738f8cba6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/views_content.info @@ -0,0 +1,13 @@ +name = Views content panes +description = Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API. +package = "Views" +dependencies[] = ctools +dependencies[] = views +core = 6.x +package = Chaos tool suite +; Information added by Drupal.org packaging script on 2015-08-19 +version = "6.x-1.14" +core = "6.x" +project = "ctools" +datestamp = "1440015241" + diff --git a/drupal/sites/default/boinc/modules/contrib/ctools/views_content/views_content.module b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/views_content.module new file mode 100644 index 0000000000000000000000000000000000000000..e54f856864bb9ac111bc2eaddc69daab157a5acb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/ctools/views_content/views_content.module @@ -0,0 +1,182 @@ +<?php + +/** + * @file views_content.module + * + * Provides views as panels content, configurable by the administrator. + * Each view provided as panel content must be configured in advance, + * but once configured, building panels with views is a little bit simpler. + */ + +/** + * Implementation of hook_menu(). + */ +function views_content_menu() { + $items = array(); + + if (!module_exists('panels')) { + $items['admin/settings/content-views'] = array( + 'title' => 'Views panes', + 'access arguments' => array('administer views content plugin'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_content_admin_page'), + 'description' => 'Configure Views to be used as CTools content.', + 'type' => MENU_NORMAL_ITEM, + ); + } + + return $items; +} + +/** + * Implementation of hook_ctools_plugin_dierctory() to let the system know + * where our content_type plugins are. + */ +function views_content_ctools_plugin_directory($owner, $plugin_type) { + if ($owner == 'ctools') { + return 'plugins/' . $plugin_type; + } +} + +/** + * Don't show Views' blocks; we expose them already. + */ +function views_ctools_block_info($module, $delta, &$info) { + if (strlen($delta) == 32) { + $hashes = variable_get('views_block_hashes', array()); + if (!empty($hashes[$delta])) { + $delta = $hashes[$delta]; + } + } + + if (substr($delta, 0, 1) != '-') { + $info = NULL; + } + else { + $info['category'] = t('Views'); + $info['icon'] = 'icon_views_block_legacy.png'; + $info['path'] = drupal_get_path('module', 'views_content'); + $info['edit form'] = 'views_content_exposed_form_pane_edit'; + $info['add form'] = 'views_content_exposed_form_pane_edit'; + $info['render callback'] = 'views_content_exposed_form_pane_render'; + } +} + +/** + * Add settings to the "exposed form in block" views. + */ +function views_content_exposed_form_pane_edit(&$form, &$form_state) { + // This is a cheesy way to add defaults only to new versions of the block + // but leave older blocks without the setting alone. We can tell because + // all older content will have something set for override_title which is + // the only pre-existing setting. + if (!isset($form_state['conf']['inherit_path']) && !isset($form_state['conf']['override_title'])) { + $form_state['conf']['inherit_path'] = TRUE; + } + + $form['inherit_path'] = array( + '#type' => 'checkbox', + '#title' => t('Inherit path'), + '#default_value' => !empty($form_state['conf']['inherit_path']), + ); +} + +/** + * Store data for the exposed form in block settings page. + */ +function views_content_exposed_form_pane_edit_submit(&$form, &$form_state) { + $form_state['conf']['inherit_path'] = $form_state['values']['inherit_path']; +} + +/** + * Render function for 'special' view blocks. + * + * We took over the render for the special view blocks so that we could + * add options to it. + */ +function views_content_exposed_form_pane_render($subtype, $conf, $panel_args, $contexts) { + $delta = str_replace('views-', '', $subtype); + + if (strlen($delta) == 32) { + $hashes = variable_get('views_block_hashes', array()); + if (!empty($hashes[$delta])) { + $delta = $hashes[$delta]; + } + } + + list($nothing, $type, $name, $display_id) = explode('-', $delta); + // Put the - back on. For views special blocks, the first character is always - but + // the explode killed it. Note that this code is mostly copied from views_block(). + $type = '-' . $type; + if ($view = views_get_view($name)) { + if ($view->access($display_id)) { + if (!empty($conf['inherit_path'])) { + $view->override_path = $_GET['q']; + } + + $view->set_display($display_id); + if (isset($view->display_handler)) { + $block = (object) $view->display_handler->view_special_blocks($type); + return $block; + } + } + $view->destroy(); + } +} + +/** + * Implementation of hook_views_api(). + * + * This one is used as the base to reduce errors when updating. + */ +function views_content_views_api() { + return array( + 'api' => 2, + 'path' => drupal_get_path('module', 'views_content') . '/plugins/views', + ); +} + +/** + * Page callback to provide the basic administration form. + */ +function views_content_admin_page() { + $form = array(); + views_content_admin_form($form); + + return system_settings_form($form); +} + +function views_content_admin_form(&$form) { + $form['ctools_content_all_views'] = array( + '#type' => 'checkbox', + '#title' => t('Make all views available as panes'), + '#description' => t("If checked, all views will be made available as content panes to be added to content types. If not checked, only Views that have a 'Content pane' display will be available as content panes. Uncheck this if you want to be able to more carefully control what view content is available to users using the panels layout UI."), + '#default_value' => variable_get('ctools_content_all_views', TRUE), + ); +} + +/** + * API function to get the view. + */ +function views_content_context_get_view(&$context) { + if (empty($context->view) || get_class($context->view) == '__PHP_Incomplete_Class') { + $context->view = views_get_view($context->data['name']); + if ($context->view) { + $context->view->set_display($context->data['display']); + } + } + + return $context->view; +} + +/** + * API function to get the view. + */ +function views_content_context_get_output(&$context) { + if (empty($context->output)) { + $view = views_content_context_get_view($context); + $context->output = $view->execute_display($context->data['display']); + } + + return $context->output; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/CHANGELOG.txt b/drupal/sites/default/boinc/modules/contrib/panels/CHANGELOG.txt new file mode 100644 index 0000000000000000000000000000000000000000..6499d218ba9fe1a290c4de1eccc1494f3e62cc94 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/CHANGELOG.txt @@ -0,0 +1,244 @@ +Panels 3.x-dev +============== +#1025716: Panels fields broken in last update. + +Panels 3.x-3.9 (2011-Jan-12) +============== +#959206: Legacy mode rendering fails with flexible due to CSS file not getting added. +#964334: Panels breaks views' row styles with the panels fields style. +#961662 by Nick Lewis: Account for pager info in simple caching. +Scrub css id and css class on panes. + +Panels 6.x-3.8 (2010-Oct-29) +============== +hook_panels_pre_render() and hook_panels_post_render() getting empty displays. +#865704: Editing mini panels styles failed badly due to missing piece of cache. +Custom style could crash if trying to enable style reuse without first enabling stylizer.module. +In Flexible, the "class" would not stick when adding a new region/row/column but would when editing. +#861426: Editing a mini panel while that same mini panel is displayed on the page resulted in a crash. +#871730: Panel nodes with IPE enabled let anyone use IPE. +#877810: Multiple "Add flexible layout" tabs appearing based on number of flexible layouts stored. +#873224 by thsutton: hook_requirements() could cause notice error. +#867340 by cedarm: Restore removed but deprecated panels_render_layout() function. +#871942 by dwatson: Invalid CSS made dragger image not appear during IPE. +#867864: Fix a admin title and edit link problems with custom content types. +#570194: Add support for the "checkall" module in the content permissions page. +#696846: Mini panels conflated displayed title with admin title. +#889824: Custom class could would cause stylizer class to become malformed. +Add a simple "Panels" row style to Views that lets you put fields in a panel layout. +Add two new Page Wizards to more easily create some of the most commonly used Panel pages. +#869766 by rupl: flexible layout builder could fail with multiple columns in only one row. (Needs clear cache to see changes in generated CSS.) +#897214: Mini panel uninstall tried to order mini panels by a non-existing field. +#893456 by omerida: Change FAPI definition of panel node "body" field to be more consistent with other node body fields. +#812658 by naxoc: Caching should take language into account. +#890086: Possible crash in flexible layout by not having CTools export.inc loaded. +#899456 by yareckon: IPE customize button needs to be reset to "static" instead of "normal". +#806874 by ximo: Allow panes to specify "render first" as well as "render last". +#920266 by dereine: Typo in cache.inc caused wsods in rare circumstances. +#879482 by mvc: Ensure Panels and CTools module files are loaded during update. Apparently could cause WSOD if not. +#917614 by jskulski: IPE broken in IE. +#906520: Improve CSS for rounded shadow boxes on IE7. +#923894 by yareckon: IPE save/cancel buttons can fail due to translation issues. +#932632 by mikeytown2: Fix notice in .install file. +#927840: Add clear-block to dashboard HTML to ensure themes do not do weird things to it. +#941806: Fix incorrect link to configure mini panel on block config page. +#869766: Fix occasional problem with flexible layout pushing the entire layout to the left in certain fixed-width only configurations. +#949310: E_STRICT violation on declaration of render_pane() method of display renderers. +#827628: "Add content" dialog could lose content with the same title as other content. +#955102: Fix notice in panel nodes when legacy rendering is not on. + +Panels 6.x-3.7 (2010-Jul-26) +============== +Experimentally introduced the In-Place Editor (IPE). +Updated Panels Stylizer to use CTools' new Export UI. +Deprecated panels_get_panels() function. This will be eventually disappear. Use panels_get_regions() instead. +#834084: Reusable flexible layout introduced. Admin UI at admin/build/panels/layouts. +Clean up flexible. Attempt to reduce the use of unnecessary divs. +Add more ability to control flexible classes. +Add ability to fix flexible canvas to a set width. +Allow disabling of scaling for IE6 in flexible. +Fixes to IPE: + Add pane would add the new pane outside region styling + Add pane would not appear in empty regions + Panes could not be dragged to empty regions + Save would lose content if they were inside stylizer styled regions +#822234 by Amitaibu: Missing url() caused IPE to not work on sites not using top level URLs. +#844062: Turned the normal drag and drop editor into a renderer plugin, made the IPE part of it. Also some fairly serious code reorganization. +Improve the renderer selection framework. This framework has no UI, but it utilizes exportables and new choices can be hand crafted. +Improve the IPE to use the proper cache if it is set, and to respect locking. +#847784: IPE displayed "Edit" link when no such link should have existed. +#843758: Legacy renderer caused "missing argument" warning when rendering. +Made it possible to override jQuery UI sortable options via settings in the renderer plugin. +Moved Panels stylizer to CTools. You must update CTools at the same time as Panels. +#737602: Generic NOT checkbox for all access tests. +#369628: Sort results by export key when bulk exporting. +#690902: Improvement to export.module integration of panel nodes. +#690814 by neclimdul: Panels mini edit form could overwrite page title. +#675220 by dereine: Provide a watchdog message if a layout can't be loaded when rendering a panel. +#713526 by psynaptic: Omit top and bottom region divs in stacked layouts if regions are empty. +#823216 by jonathan1055: Put quotes around url() in rounded corners CSS. +#603150 by hefox: Protect against the panels node add form being used in unusual places. +#841824 by levacjeep: Extend panels_edit and panels_edit_layout to allow more options with the $destination. +#842976 by drewish: Make sure the theme knows path and file information for plugin supplied themes. +#743850 by foripepe: Add delete panel node permissions. +#532900: Flexible sometimes did not update links when region settings changed. +#723036: Node pane previews did not include node content as they should. +#831216: It should not be possible to remove the Canvas. +#216076: Make sure that empty panes are not rendered. Note: Legacy mode region styles can still render empty panes anyway. +#609626: Static caching loading mini panels. +#848712 by josh_k: Use panel nodes with IPE. +#860306 by jcmarco: "Substitutions" fieldset would not open due to missing js. +#856964: "Custom style" selection was not working. +#863302: Allow IPE to cope with empty panes. +#865344: by jrockowitz: Panel node access hook should use $account. + +Panels 6.x-3.5 (2010-May-28) +============== +Replaced panels_load_include() with ctools_include(). +Restored (and deprecated) panels_print_layout(), as other modules were relying on it. + +Panels 6.x-3.4 (2010-May-19) +============== +Introduced Panels Stylizer. +Removed superfluous function, panels_sanitize_display(). +#655268: Fix a problem retrieving cached content created by #634746. +Removed the old and crufty panels_print_layout(). +#745808 by Robbert: use number_format() in flexible width calculations to ensure locale settings cannot bork generated CSS. +Stopped wasting cycles trying to render a mini panel in a block when we know the mini panel doesn't exist. +#765978 by joshk: Added watchdoggery and a hook to panels_display_save(). +#746568 by mgriego: Disable block caching for mini panels. +#798954 by dixon: Pass $form_state to style plugins' validate and submit callbacks. +#779012 by c960657: implement the callback for a single content_type subtype in panels_mini to improve performance with large numbers of mini panels. +#763584 by neclimdul: Add a link to the block configuration page for mini-panels that takes the user to edit that mini- panel. +Security updates: protect the importer with the 'use PHP for block visibility' permission. + +Panels 6.x-3.3 (2010-Feb-01) +============== + +#612850: Fix crash bug with panes referencing deleted/missing views. +#614178: Transition to panels-pane.tpl.php caused empty panes to display again. +#634746 by joshk: Allow pane caching to modify the content during cache storage. +#612116 by johnskulski: panels-pane preprocess was incorrectly rendering $links +#612704 by c960657: panels_get_pane_content() inappropriately created a blank context when no contexts were available. +#618624 by johnskulski: Better classes for panel panes. +#651306 by joachim: Add "edit any panel node" permission. Not sure why this was never there. +#497042: Add update.php to remove unused panels_page_router_store table, if it exists. +#683162: Convert all plugins to use new $plugin = array() format. This is less brittle than the specially named hook. +#543898: Fix notice error when a layout has no regions. +#647706: Mini panel names can only be 32 characters, but the form failed to restrict the limit. +Introduce the Panels stylizer module which builds on the CTools stylizer base to create user definable, recolorable styles. + +Panels 6.x-3.2 (2009-Oct-21) +============== + +#606980 by Deciphered and sethfreach: Typo caused panel-pane class to disappear if another class was assigned. +#607242: Using the wrong variable in hook_block can cause title to not be overridable. +#608062: Visibility rules did not appear in the list when added to a pane (though they still applied). + +Panels 6.x-3.1 (2009-Oct-15) +============== + +#552846 by eMPee584: Fix notice with tablesorts on mini panels page if no mini panels exist. +#568218: Links to clone, export, delete/revert, enable/disable variants from the main summary page were incorrect and led to an operation trail not found message. +#533724: Prevent Panels from upgrading while uninstalled, as that upgrades into broken pages. +#529816: Allow flexible layout to add custom classes to each region. +Rearrange the pane dropdown menus to be better organized and look a little nicer. +Add a new field to allow setting a panel title from one of its panes. +#562560 by Damien McKenna: Integration with export.module +#583172 by jacine: Turn panel pane into a template, as it always should have been. +#604404: Make sure caching does not trigger for form POSTs. + +Panels 6.x-3.0 (2009-Aug-19) +============== + +#529258 by stella: Attempting to modify CSS properties on mini panel causes ajax failure. +#537430 by dereine: Fix untranslatable strings in panels dashboard template. +#530104 by stella: Fix import problem with mini panels. +#535606: Mini panel deletion deleted all block config of all mini panels. +#539418 by esmerel: Remove reference to panel page from module description. +#535722: Fix incorrect "title" tag on categories in add content modal. +Fix a bug with drag and drop UI that caused panes to break after other panes were added. +#538900: Fix bug with flexible when having multiple regions of the same name if they have a space. +#552014: Hide Substitutions fieldset if there are no contexts. +#552006: Add Content modal now opens to explanatory text instead of the first category. +#553392 by lee20: Fix node allowed layouts not properly respected on edit layout screen. + +Panels 6.x-3.0-rc1 +================== + +#515316: Add permission to view Panels admin dashboard. +#298174: Recursion defense for mini panels. +#502670: Extra HTML designed only for flexible layout admin accidentally rendered. +#507516: "Default" panel style on regions not being properly utilized. +#476440: Seriously, cloning variants really realy fixed. +#518360 by joshk: Panels node form doesn't have format properly associated. +#525340 by markus_petrux: Dashboard improperly initializing a variable. +#460902 by dmmckenna: Fix problem installing panels from an install profile. +#488278: Preview on panel nodes prior to creation caused errors. +#475920: Create "use panels dashboard" permission to more easily control who can and cannot use it. +#384552: Fix incompatibilities with theme developer. Drag & drop screen does not need to be themable. + +Panels 6.x-3.0-beta4 +==================== +Note: beta3 skipped to stay even with CTools beta numbers. +Removal of non-functioning bulk export module in favor of the new one in CTools. +Update to require CTools API 1.1.0 +Updates to work with the new Page Manager UI in CTools. + +Panels 6.x-3.0-beta2 +==================== +Update to require CTools based upon its advertised API version number. +Update code to ensure that the dead 'panels simple cache' module is really dead. +Attempt to go back further in history for a Panels 1 upgrade path. +Fix for making sure Panels completely disables itself if using incompatible version of CTools. +Update CSS caching on panel page and panel context to use ctools_css_store instead of remembering the filename. +Infinite loop protection in panel nodes. +#459078: Provide the "read more" flag for teasers of panel nodes. +Fix broken styling when dragging a panel pane. +Integrate with CTools tab system so we can add edit tabs to all our panel pages. +#454208: pgsql does not support concat(), so use || instead for postgres. +#445828: Remove "Settings" link if a content type has no settings form. +#460200: Allow regions and columns that have only 'fixed' width items. Disallow changing a 'fixed' item to 'fluid.' + +Panels 6.x-3.0-beta1 +==================== + +#422712: Panel page import button went to wrong place. +#423288: Profile template plugin had wrong path. +#424176: Panel nodes: Remove unused layout screen, fix some notice errors, give context a description. +New simpler panel page task that doesn't bother with handlers at all. +#317121: Respect 'hide title' option in display settings. +#422404: Update to exportables left mini panels kind of broken. +#422180 by joshk: Fix panel node_access to accept incoming $account. +Moved content types to CTools. +Better add content dialog. +#437742 by jcmarco: Missing include. +#440142 by jcmarco: Did not change panels_get_content_types to ctools_get_content_types. +Add a live preview widget to the panel content edit page. +Fix panel page type to actually respect the contexts. +Upgrades from as far back as Drupal 5 can now be supported. +Rearranged the menus, created the Panel dashboard. +Returned the allowed content settings form to panel page +Added allowed layouts to settings form for panel pages, nodes, minis. +#362754 by dereine: Fix invalid XHTML in 3col 33/34/33 template. +#375686: Create panels_get_current_page_display() to replace the old panels_get_current_page() function. +#424798: Respond to a cloned handler by properly cloning the display as well. +#424290: Ensure content.inc is loaded during panels display save so that everything can be found. +#422090: Ensure the first item added to a row is fluid. Fixed can then be added after that. + +Panels 6.x-3.0-alpha3 +===================== +Note: This changelog is incomplete, as it was started sometime after alpha2.ls + +#349979 by Dave Reid: Proper use of link alter. +#374628: Add a check for broken display to the admin summary to prevent crashes. +Retool flexible layout into a nice javascripty visual layout builder. +Retool mini panels to use ctools export class and provide a .inc file for its content type as a better example. +Store a panel task handler's display in the database. +Add a mechanism to fetch information about just one content subtype (i.e, single view, single block) instead of fetching them all. +Overhaul node_content_type creating a .inc file. +Add 'content type' property to content types. +Add 'defaults' property to content types. +Panels views cleanup, including making exposed form blocks available. +#391788 by guix: Simple cache should not unserialize data that is now already unserialized. +#367635 by lee20: View title built too early and so lost arguments. diff --git a/drupal/sites/default/boinc/modules/contrib/panels/D6UPDATE.txt b/drupal/sites/default/boinc/modules/contrib/panels/D6UPDATE.txt new file mode 100644 index 0000000000000000000000000000000000000000..5fad7f507ffd506735d2bbc0e4d43bd88fefd6fa --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/D6UPDATE.txt @@ -0,0 +1,52 @@ +CHANGES DURING D6 UPDATE TO PANELS 3 + +ALL PLUGINS +=========== + +Function to advertise directory for plugins: + hook_ctools_plugin_directory($module, $plugin) + +LAYOUTS +======= + +All layouts should use templates +'icon' now uses the defined path and should no longer have path built in. +'css' now uses defined path and should no longer have path built in. +DOCUMENTATION NOTE: You can just copy any layout css file directly to your theme. It should no longer be in theme/layouts directory. +administrative view of a layout can now have its own theme function. + +CONTENT TYPES +============= + +panels_node_legacy module renamed to panels_node_content.module +-- NEED UPDATE TO RENAME IN SYSTEM TABLE. + +'title callback' now has $subtype as the first argument. +'render' now has $subtype as the first argument. +'content_types' now 'content types'. +New 'content type' to fetch information a single content type so we don't have +to load all of them all the time. +New 'defaults' array in either the type or subtype declaration to provide +defaults for the add form. + +CONTEXTS +======== + +Function signature on submit and validate handlers now: ($form, &$form_values, &$form_state) +Moved to CTOOLS + +RELATIONSHIPS +======== + +Function signature on submit and validate handlers now: ($form, &$form_values, &$form_state) +Moved to CTOOLS + +ARGUMENTS +======== + +Function signature on submit and validate handlers now: ($form, &$form_values, &$form_state) +Moved to CTOOLS + +When argument plugins fail to load a context at runtime, they must now return +error codes instead of FALSE or NULL (previously the practice). The error codes, +and their respective documentation, can be found at the top of panels.module. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/INSTALL.txt b/drupal/sites/default/boinc/modules/contrib/panels/INSTALL.txt new file mode 100644 index 0000000000000000000000000000000000000000..a883666cf839c72f77506b0bdd03811b128dcac7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/INSTALL.txt @@ -0,0 +1,8 @@ + +Place the module files in the appropriate directory. If you're not sure, +try 'sites/all/modules'. + +Then navigate to administer >> site building >> modules and activate +the panels module, along with any of the accompanying side modules you'd like to use. +The Panels module itself only provides an API - you MUST install these other modules +if you want to do much of anything. diff --git a/drupal/sites/default/boinc/modules/contrib/panels/KNOWN_ISSUES.txt b/drupal/sites/default/boinc/modules/contrib/panels/KNOWN_ISSUES.txt new file mode 100644 index 0000000000000000000000000000000000000000..66963675f6e727f4832046e75131bccce2345646 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/KNOWN_ISSUES.txt @@ -0,0 +1,91 @@ + +Known Issue http://drupal.org/node/191771 + 'Node' panes can have two titles or have two title areas. + Cause: + Content that comes into a pane is already formatted, and this happens + in theme('node'). theme('node') assumes it will be printing a title + most of the time. However, Panels wants the titles of panes to be + consistent, so it removes the title from the node to prevent your + node.tpl.php from printing it. The result is often an empty h2 which + has odd effects. + Solution: + Add an if statement to your node.tpl.php to prevent printing that h2 + if $node->title is empty. + +Known Issue http://drupal.org/node/186454 + Internet Explorer is really bad about making the rightmost panel + fall beneath the others. + Cause: + Internet explorer calculates margins and padding differntly from + everyone else, and this makes it entirely too easy for widths + to add up to greater than the amount of allotted space, despite + using percentage widths. + Solution: + There are two solutions to this problem: + 1) In your theme, try to eliminate padding from the the <div> + that directly contains your content; you can do this by + adding an empty <div> inside it that surrounds the content + and very specifically is set to margin: 0 and padding: 0 + + 2) if that doesn't work, override the widths of the panel-panel + divs and reduce them by 1 or 2%; usually this will give IE + enough space to quit pushing things around. + +Known Issue http://drupal.org/node/154351 + TinyMCE, FCKEditor and other wysiwyg editors really blow up on Panels + content editing. + Cause: + The modal dialogs that Panels uses are very particular about javascript + and these editors are too much for them. Also, these editors get + cranky about complicated forms with several text areas. + Solution: + Disable these editors on all of your panels admin pages. The important + URLs are admin/panels/* and panels/ajax/*. More details instructions + may follow if someone familiar with these systems submits a patch at + the above drupal.org URL. + +Known Issue http://drupal.org/node/180650 + The rounded corners style shows up as just a small graphic rather than + a full box around the panels as it shoujld. + Cause: + The rounded corners CSS relies on the ID for the panel, but the ID is + optional. + Solution: + Make sure your panel has an ID of some sort. With mini panels there is + no easy workaround as mini panels currently do not have IDs of their + own. + +Known Issue http://drupal.org/node/165745 + You see a message similar to this: + Table 'drupal.panels_info' doesn't exist query: SELECT * FROM panels_info + WHERE path = 'front_page_new' in... + + The important piece of information is 'panels_info'. + Cause: + The Meta Tags module (also known as nodewords.module) directly reads the + the panels tables and modifies its forms to add the tags. Unfortunately + for this module, Panels has changed *greatly* in the leap from 1.0 to + 2.0 and the tables aren't the same. However, the nodewords module doesn't + yet know this. Look in the nodewords issue queue for panels patches and + you should find something. + +Known Issue http://drupal.org/node/153399 + The drag and drop content UI doesn't seem to work at all under Safari. + + Cause: + Safari 2 has some serious problems with the javascript code. + Solution: + Upgrade to Safari 3 if possible. If not, use an an alternative browser + such as Firefox or Opera. + +Known Issue http://drupal.org/node/207859 + When using the secure pages module, the Panels administrative UI gives + unhelpful "An error occurred" popups when trying to add or edit content. + + Cause: + The secure pages module tries to move the entire administrative section + of the site to HTTPS, but Panels' AJAX calls are using a path that + secure pages doesn't know about. When trying to make non-secure ajax calls + from a secure page, the browser denies the call. + Solution: + The solution is to simply add panels/* to your Secure Pages configuration. \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/LICENSE.txt b/drupal/sites/default/boinc/modules/contrib/panels/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..d159169d1050894d3ea3b98e1c965c4058208fe1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/drupal/sites/default/boinc/modules/contrib/panels/README.txt b/drupal/sites/default/boinc/modules/contrib/panels/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..557befd868b8c7cfa6128f24115394fe46ffdfbf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/README.txt @@ -0,0 +1,6 @@ + +Welcome to Panels 2. + +A little documentation should go here, but Panels 2 is a beast - you're best +off checking the online handbook on Drupal.org, or the developer/API docs, +which are available at http://doxy.samboyer.org/panels2/ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/css/panels-dashboard.css b/drupal/sites/default/boinc/modules/contrib/panels/css/panels-dashboard.css new file mode 100644 index 0000000000000000000000000000000000000000..a7efeae18bc97ba1439cfc41a929066870c3a1a4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/css/panels-dashboard.css @@ -0,0 +1,62 @@ + +.dashboard-entry .dashboard-link { + font-size: 120%; + font-weight: bold; +} + +.dashboard-entry .dashboard-icon img { + vertical-align: middle; +} +.dashboard-title { + font-weight: bold; + font-size: 140%; + margin-bottom: .5em; +} + +.dashboard-link form input { + margin: 0; +} + +.dashboard-link form select { + margin: 0; +} + +.dashboard-left { + width: 47%; + float: left; +} + +.dashboard-right { + margin-left: 2em; + width: 47%; + float: left; +} + +.dashboard-question { + margin-top: 14em; + padding: 1em; + text-align: center; +} + +.dashboard-content table { + margin: 0; + width: 100%; +} + +.dashboard-content { + padding: 0 1em; +} + +.panels-dashboard .links { + text-align: right; +} + +.dashboard-pages .page-manager-page-operations { + text-align: right; +} + +.dashboard-block { + padding-bottom: 1em; + border-bottom: 1px dotted #ddd; + margin-bottom: 1em; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/css/panels.css b/drupal/sites/default/boinc/modules/contrib/panels/css/panels.css new file mode 100644 index 0000000000000000000000000000000000000000..99552a94b9ba4842e62ca286ffcc4ef59acb76fb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/css/panels.css @@ -0,0 +1,50 @@ + +div.panel-pane div.admin-links { + font-size: xx-small; + margin-right: 1em; +} + +div.panel-pane div.admin-links li a { + color: #ccc; +} + +div.panel-pane div.admin-links li { + padding-bottom: 2px; + background: white; + z-index: 201; +} + +div.panel-pane div.admin-links:hover a, +div.panel-pane div.admin-links-hover a { + color: #000; +} + +div.panel-pane div.admin-links a:before { + content: "["; +} + +div.panel-pane div.admin-links a:after { + content: "]"; +} + +div.panel-pane div.panel-hide { + display: none; +} + +/** For IE we add the class via js; for other browsers we rely on :hover **/ +div.panel-pane div.panel-hide-hover, +div.panel-pane:hover div.panel-hide { + display: block; + position: absolute; + z-index: 200; + margin-top: -1.5em; +} + +div.panel-pane div.node { + margin: 0; + padding: 0; +} + +div.panel-pane div.feed a { + float: right; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/css/panels_admin.css b/drupal/sites/default/boinc/modules/contrib/panels/css/panels_admin.css new file mode 100644 index 0000000000000000000000000000000000000000..496fd64f0a3f079818c28b535d95a2732530b435 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/css/panels_admin.css @@ -0,0 +1,162 @@ + +.layout-link { + float: left; + padding: 1em; + width: 125px; + height: 160px; +} + +.layout-link img { + margin-left: auto; + margin-right: auto; +} + +/* general style for the layout-icon */ +.layout-icon .caption { + width: 90px; + margin-bottom: 1em; +} + +/* styles for the basic panel-%implementation% edit page */ +.layout-container, +.right-container { + float: right; + padding: 0 0 0 .5em; + margin: 0; + width: 48.5%; +} + +.info-container, +.left-container { + padding-right: .5em; + width: 48.5%; +} + +.right-container fieldset, +.left-container fieldset, +.layout-container fieldset { + margin-top: 0; +} + +.layout-container .form-item { + margin: 0; +} + +.layout-container .form-submit { + margin-top: 1em; +} + +.layout-container .layout-icon, +.left-container .layout-icon { + float: right; + margin-left: .5em; +} + +.content-list ol { + padding-left: 0; + list-style-position: inside; +} + +.content-list dt { + font-weight: bold; +} + +.content-list dd { + margin-left: 2em; +} + +/* styles for the choose layout page */ +.panels-layouts-checkboxes .form-checkboxes .form-item, +#panels-choose-layout .form-radios .form-item { + float: left; + margin-right: .5em; + width: 90px; +} + +.panels-layouts-checkboxes .form-checkboxes .form-item .layout-icon, +#panels-choose-layout .form-radios .form-item .layout-icon { + float: none; + height: 11em; + width: 90px; +} +.panels-layouts-checkboxes .form-checkboxes .option, +#panels-choose-layout .form-radios .form-item .option { + width: 50px; + display: block; + text-align: center; +} + +.panels-layouts-checkboxes .form-submit, +#panels-choose-layout .form-submit { + clear: left; +} + +.panels-layouts-checkboxes .panels-layout-list label, +#panels-choose-layout .panels-layout-list label { + width: 300px; + float: left; + clear: left; + background: url(../images/go-right.png) right no-repeat; + margin-right: 20px; +} + +.panels-layouts-checkboxes .panels-layouts-category { + font-weight: bold; + width: 100%; + float: left; +} + +.panels-layouts-checkboxes .description { + clear: left; +} + +.change-layout-display .layout-icon { + float: left; +} + +.change-layout-display > img { + padding: 25px 25px 25px 0; + float: left; +} + +table .operation { + text-align: right; + padding-right: 6px; +} + +table .argument-operation input { + padding: 0; + margin: 0; + position: relative; + top: 3px; +} + +.panels-admin-view { + padding: 1em; + border: 1px dotted black; + margin-bottom: 1em; +} + +tr.changed td { + background-color: #FFFFDD !important; +} + +tr.changed td span.star { + font-weight: bold; + color: #E09010; +} + +td select { + margin: 0; + padding: 0; +} + +.panels-style-settings, +.panels-style-settings-box, +#panels-style-setting { + float: left; +} + +.panels-style-settings-box .form-item { + margin: 0 1em 0 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/css/panels_dnd.css b/drupal/sites/default/boinc/modules/contrib/panels/css/panels_dnd.css new file mode 100644 index 0000000000000000000000000000000000000000..c4e1e1449545f769316c512da802494cd9f88d30 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/css/panels_dnd.css @@ -0,0 +1,629 @@ + +#panels-dnd-main { + margin: 0.5em 0; +} + +#panels-dnd-main div.panels-display { + padding: 0 0 .5em 0; + border: 1px dashed #ddd; + background: #f8f8f8; + -webkit-border-radius: 0.333em; + -moz-border-radius: 0.333em; +} + +#panels-dnd-main div.panels-display h2.label { + color: #555; + text-shadow: #fff 1px 1px 1px; + text-align: center; + font-size: 13pt; + margin: 0 0 .5em 0; + padding-right: 16px; + vertical-align: middle; +} + +#panels-dnd-main div.panels-display .pane-add { + float: left; + margin: 2px; + background: #999; + border: 1px solid #fff; +} + +#panels-dnd-main div.panels-display .pane-add-link { + position: absolute; + display: block; + width: 16px; + height: 16px; + float: left; + margin: 2px 2px 2px 4px; +} + +div.panels-set-title-hide .panels-set-title { + display: none !important; +} + +/* Add Icon */ +#panels-dnd-main div.panels-display .pane-add-link { +} +#panels-dnd-main div.panels-display .pane-add-link img { + display: none; +} +#panels-dnd-main div.panels-display .pane-add-link a.ctools-dropdown-image-link { + border: none; + width: 16px; + height: 18px; + float: left; + background: url('../images/sprite.png') no-repeat 0 -1178px; +/* background: url('../images/sprite.png') no-repeat -166px -582px; */ +} + +.panel-portlet { + padding: 0em; + background: #ffffff; + border: 1px solid #bbb; +} + +div.panels-set-title-hide .panel-pane-is-title { + border: 1px solid #bbb; +} + +.panel-pane-is-title { + border: 2px solid #777; +} + +/* Cog Icon */ +.panel-portlet .buttons a img { + display: none; + margin: 0; +} +.panel-portlet .buttons a.ctools-dropdown-image-link { + border: none; + width: 16px; + height: 16px; + margin: 0 5px 0 0; + float: none; + display: block; + background: url('../images/sprite.png') no-repeat 0 -1178px; +} + +#panels-dnd-main .panel-pane, +#panels-dnd-main .helperclass { + margin: .5em; +} + +#panels-dnd-main-form .inline-icon-help { + vertical-align: middle; + margin: 2px 1px; +} + +.panel-pane.hidden-pane { + background: #f8f8f8; +} + +.panel-portlet .pane-content { + margin: .5em 0 .5em 0; + padding: 0 .25em 0 .25em; + display: none; /* initially hidden */ +} + +.panel-portlet .grabber { + width: 100%; + height: 20px; + cursor: move; + margin: 0 0 0.5em 0; + overflow: hidden; + background: #b3b3b3 url('../images/bg-shade-medium.png') repeat-x 0 100%; + color: #fff; + text-shadow: #555 1px 1px 1px; + border-color: #999; + font-weight: bold; +} + +.panel-portlet.hidden-pane .grabber { + background-color: #888; +} + +.panel-portlet .changed div.grabber { + background-color: #FFFFDD !important; + border-bottom: 1px solid #3D9CD7 !important; + color: black !important; +} + +.panel-portlet .changed.hidden-pane div.grabber { + background-color: #B4B488 !important; + border-bottom: 1px solid #3D9CD7 !important; +} + +.panel-portlet .changed div.grabber span.star { + font-weight: bold; + color: #E09010; +} + +.panel-portlet .grabber:hover { + color: #fff; + background-color: #2F78A5; +} + +.panel-portlet.hidden-pane .grabber:hover { + background-color: #666; +} + +.panel-portlet .grabber:active { + background-color: red; +} + +.panel-portlet .grabber:hover, +.panel-portlet .grabber:active { + background: #858585 url('../images/bg-shade-dark.png') repeat-x 0 100%; + color: #fff; + text-shadow: #333 1px 1px 1px; + border-color: #858585; +} + +.panel-portlet .grabber .text { + margin-left: 3px; + font-size: 90%; + line-height: 20px; +} + +.panel-portlet .buttons { + float: right; + padding: 0; + margin: 0; +} + +.panel-portlet .buttons input { + margin: 0; + padding: 0; + display: inline; +} + +.panel-portlet .buttons a img { + margin: 2px 1px; +} + +.panel-portlet .pane-title { + font-size:110%; + cursor: pointer; +} + +.panel-portlet .panel-pane-collapsible { + margin: 0; + padding: 0; +} + +.panel-portlet .toggle { + float: left; + width: 21px; + height: 21px; + cursor: pointer; + background: url('../images/sky.png') no-repeat 6px -245px; +} + +.panel-portlet .toggle-collapsed { + background: url('../images/sky.png') no-repeat 6px -1021px; +} + +/* CSS to guide a user to a place to drop */ +#panels-dnd-main .helperclass { + border: 1px dashed red; +} + +#panels-dnd-main .hoverclass { + border: 1px solid red !important; +} + +/* CSS for an area if something can be dropped in it */ +.panels-modal-content { + background: #fff; + color: #000; + padding: 0; + margin: 2px; + border: 1px solid #000; + width: 600px; + text-align: left; +} + +.panels-modal-content .modal-title { + font-size: 120%; + font-weight: bold; + color: white; + overflow: hidden; + white-space: nowrap; +} + +.panels-modal-content .modal-header { + background-color: #2385c2; + padding: 0 .25em 0 1em; +} + +.panels-modal-content .modal-header a { + color: white; + float: right; +} + +.panels-modal-content .modal-content { + padding: 0 1em; + overflow: auto; + width: 575px; + height: 400px; +} + +.panels-modal-content .modal-form { +} + +.panels-modal-content .form-checkboxes .form-item { + float: left; + width: 24%; +} + +.panels-hidden, +.panels-js-only { + display: none; +} + +a.close { + color: white; +} + +a.close:hover { + text-decoration: none; +} + +a.close img { + position: relative; + top: 1px; +} + +.panels-section-title { + clear: left; + border-bottom: 1px solid #ddf; + margin-bottom: .5em; + text-align: left; +} + +.panels-section-decorator { +} + +.panels-add-content-modal .panels-modal-add-category { + display: block; + border-bottom: 1px solid white; + padding-left: .5em; + margin-left: -2px; + position: relative; +} + +.panels-add-content-modal .panels-modal-add-category.active { + background: url(../images/arrow-active.png) center right no-repeat white; + border-right: none; +} + +.panels-add-content-modal { + background: url(../images/bg-content-modal.png); + height: 100%; + margin: -1em; + padding-top: 1em; + padding-left: 175px; + position: relative; +} + +.panels-section-columns { + height: 100%; + overflow: auto; +} +.panels-section-column { + width: 48%; + float: left; +} + +.panels-section-column .inside { + padding: 0 1em; +} + +.panels-section-column-categories { + width: 173px; + margin-left: -173px; +} + +.panels-categories-description { + padding: 0 1em; + text-align: center; + vertical-align: center; +} + +* html .panels-section-column-categories { + left: 173px; + position: relative; +} + +.panels-section-column-categories .panels-categories-box { + border-top: 1px solid white; + margin-bottom: 1em; +} + +.panels-section-column-categories .inside { + padding: 0; + } + +.panels-section-column-categories .content-type-button { + padding-left: 10px; +} + +.panels-modal-add-category { + color: #5b5b5b !important; + font-weight: bold; + line-height: 2em; +} + +.panels-section { + margin-bottom: 1em; +} + +.panels-section-column .content-type-button { + font-size: 8pt; + line-height: 1em; + overflow: hidden; + text-align: left; +} + +.content-type-button img { + border: 2px solid white; + float: left; +} + +.content-type-button img:hover { + border: 2px solid blue; +} + +.content-type-button div { + width: 85%; + top: -5px; + left: 2px; + float: left; + padding-left: 3px; + padding-top: 5px; +} + +#panels-preview .modal-throbber-wrapper { + width: 100%; + text-align: center; + margin-left: auto; + margin-right: auto; +} +/** modal forms CSS **/ +.panels-modal-content .form-item label { + width: 8em; + float: left; +} + +.panels-modal-content .form-item label.option { + width: auto; + float: none; +} + +.panels-modal-content .form-item .description { + clear: left; +} + +.panels-modal-content .form-item .description .tips { + margin-left: 2em; +} + +.panels-modal-content .no-float .form-item * { + float: none; +} + +.panels-modal-content .modal-form .no-float label { + width: auto; +} + +.panels-modal-content .modal-form fieldset, +.panels-modal-content .modal-form .form-checkboxes { + clear: left; +} + +#edit-configuration-nid { + clear: left; +} + +.option-text-aligner .form-item { + float: left; + padding: .25em 1em .25em 0; + margin: 0; +} + +.option-text-aligner { + clear: both; + width: 100%; + padding: 0; + margin: 0; +} + + +#panels-dnd-main div.panel-pane div.ctools-dropdown-container-wrapper { + margin-left: -158px; + margin-top: -4px; +} + +/* +html.js div.panels-display-links div.ctools-dropdown-container { + width: 275px; +} + +html.js div.panels-display-links div.ctools-dropdown-container ul li li a { + width: 250px; +} + +html.js div.panels-display-links div.ctools-dropdown-container ul li a { + width: 270px; +} +*/ + +#panels-dnd-main .panel-pane .pane-title { + padding: 0.25em 0.5em; +} +#panels-dnd-main .panel-pane .pane-title:after { + font-size: 0.8em; + color: crimson; + letter-spacing: normal; + display: block; +} +#panels-dnd-main .panel-pane.hidden-pane .pane-title:after { + content: " status: hidden"; +} +#panels-dnd-main .panel-pane.changed .pane-title:after { + content: " status: changes not saved"; +} +#panels-dnd-main .panel-pane.hidden-pane.changed .pane-title:after { + content: " status: hidden & changed"; +} + +/* @end */ + + +/* @group CTools Dropdown */ +#panels-dnd-main .ctools-dropdown a.ctools-dropdown-text-link, +html.js div.panels-display-links a.ctools-dropdown-text-link { + + background: url('../images/arrow-down-light.png') 0 3px no-repeat!important; + padding-left: 12px; +} +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container, +html.js div.panels-display-links div.ctools-dropdown-container { + width: 160px!important; + background: #fff url('../images/bg-shade-white-lrg.png') repeat-x 0 100%; + border: solid 1px #ddd!important; + margin: 0!important; +/* padding: 0.5em!important; */ + -webkit-border-radius: 0.333em; + -moz-border-radius: 0.333em; + -webkit-box-shadow: 0.333em 0.333em 0.333em rgba(0, 0, 0, 0.25); + font-size: 0.9em; + font-weight: bold; +} + +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li, +html.js div.panels-display-links div.ctools-dropdown-container ul li { + + text-decoration: none; + padding: 0; + margin: 0; + color: #555!important; + text-shadow: #fff 1px 1px 1px; +} +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li span.text, +html.js div.panels-display-links div.ctools-dropdown-container ul li span.text { + + font-style: normal; + color: #000; + font-weight: bold; +} + +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li a, +html.js div.panels-display-links div.ctools-dropdown-container ul li a { + color: #555!important; + font-weight: normal; + width: auto; + padding: 0 10px; +} + +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li span.panels-text, +html.js div.panels-display-links div.ctools-dropdown-container ul li span.panels-text { + width: auto; + padding: 0 10px; +} + +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li .panels-italic, +html.js div.panels-display-links div.ctools-dropdown-container ul li .panels-italic { + font-style: italic; +} + +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li span.dropdown-header, +html.js div.panels-display-links div.ctools-dropdown-container ul li span.dropdown-header { + background-color: #fefefe; + padding: 0 10px; +} + +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li .panels-sub-menu ul li a, +html.js div.panels-display-links div.ctools-dropdown-container ul li .panels-sub-menu ul li a, +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li .panels-sub-menu span.panels-text, +html.js div.panels-display-links div.ctools-dropdown-container ul li .panels-sub-menu span.panels-text { + padding: 0 20px; +} + +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container hr, +html.js div.panels-display-links div.ctools-dropdown-container hr { + border: 0; + color: #ddd; + background-color: #ddd; + height: 1px; +} + +/* +html.js #panels-dnd-main div.ctools-dropdown div.ctools-dropdown-container ul li a:hover, +html.js div.panels-display-links div.ctools-dropdown-container ul li a:hover { + background: none!important; + color: #000!important; +} +*/ +/* @end */ + +/* @group Modal */ +/* Account for the extra div coming from ctools_modal_form_render() */ +div.messages div.messages { + background: none; + border: none; + margin: 0; + padding: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; +} +div.ctools-modal-content .modal-header { + background: #fff url('../images/bg-shade-light.png') repeat-x bottom left; + color: #777; + display: block; + font-weight: 700; + letter-spacing: normal; + padding: 0.25em 1em; + -moz-border-radius-topleft: 0.5em; + -moz-border-radius-topright: 0.5em; + -webkit-border-top-left-radius: 0.5em; + -webkit-border-top-right-radius: 0.5em; +} +div.ctools-modal-content .modal-title { + font-size: 120%; + font-weight: bold; + text-shadow: #fff 1px 1px 1px; + color: #555; +} +div.ctools-modal-content a.close { + color: #666; + font-weight: normal; + padding-left: 1.6em; + background: url('../images/sprite.png') no-repeat -166px -1686px; +} +div.ctools-modal-content a.close img { + display: none; +} +/** modal forms CSS **/ +div.ctools-modal-content .form-item label { + width: 100%; + float: none; + clear: both; +} +div.ctools-modal-content .resizable-textarea { + width: 100%; + margin-left: 0; + margin-right: 0; +} +div.ctools-modal-content { + font-size: 12px; + border: solid 1px #ddd; + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + -webkit-box-shadow: -1em 1em 1em rgba(0, 0, 0, 0.5); +} +#modalBackdrop { + position: fixed!important; + background-color: #000!important; +} +/* @end */ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/css/panels_page.css b/drupal/sites/default/boinc/modules/contrib/panels/css/panels_page.css new file mode 100644 index 0000000000000000000000000000000000000000..1d731b97895dd536e29eb4d6a24540a218947e4e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/css/panels_page.css @@ -0,0 +1,14 @@ + +div.panels-page-type-container { + clear: left; +} + +div.panels-page-type-container .form-checkboxes .form-item { + float: left; + width: 15em; +} + +#panels-page-settings .form-submit { + display: block; + clear: left; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/help/api.html b/drupal/sites/default/boinc/modules/contrib/panels/help/api.html new file mode 100644 index 0000000000000000000000000000000000000000..e0d2d4afea056dbec9567e059c48c0d36e47be44 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/help/api.html @@ -0,0 +1,44 @@ +<p>Panels is a pluggable rendering engine. Apart from its datastructure, almost nothing in Panels is hardcoded; every level of its rendering process is controlled by plugins (of the <a href="topic:ctools/plugins">CTools</a> variety), and therefore can be overriden. Some of these plugins' behaviors are obvious from the UI, whereas others are much more under-the-hood.</p> +<p>Most site builders and module authors will find that plugins are the only way they need to interact with Panels to do what they want. However, if you are building whole new UIs/applications that are to be driven by the Panels engine, you'll also need the more traditional API that manages Panels editing and CRUD. Panels Node and Mini Panels are examples of 'applications' in this sense, as is <a href="http://drupal.org/project/og_panels">OG Panels</a>.</p> +<p>This page is divided into two sections, the first dealing with Panels' rendering system & the plugins the drive it, and the second with the requirements for creating a Panels-driven application/UI. The former is a good starting place and should be of interest to anyone wanting to begin working with the Panels API.</p> + +<h2>The Panels Rendering System</h2> +<p>Panels' rendering system takes a fully-loaded panels_display object and turns it into HTML. It doesn't care how that object was built or where it comes from - it's just a rendering engine. So long as the calling code provides a well-formed panels_display object, the engine will spit out HTML. Exactly how that process works is determined entirely by plugins.</p> +<p>Panels utilizes eight different types of plugins within its rendering system, four owned by Panels and four by CTools. Let's run through that list.</p> +<dl> +<dt><a href="topic:panels/plugins-layout">Layout plugins</a></dt> +<dd><em>Owned by Panels.</em></dd> +<dd>Layout plugins provide the HTML output skeleton for any panel: they define a set of regions and (optionally) accompanying CSS/JS, very analogous to how themes define block regions. While layout plugins with complex logic are possible (the Flexible layout, for example), most layouts are nothing more than a region list, a tpl.php skeleton, and some CSS.</dd> +<dt><a href="topic:panels/plugins-style">Style plugins</a></dt> +<dd><em>Owned by Panels.</em></dd> +<dd>Style plugins control the markup that wraps both individual panes and whole panel regions. A basic style plugin need not provide more than some basic CSS and a theme function or tpl.php file.</dd> +<dt><a href="topic:ctools/plugins-style-bases">Style Bases</a></dt> +<dd><em>Owned by CTools.</em></dd> +<dd>Panels implements the 'style_bases' plugin type in order to interact with the Stylizer system, which technically lives in CTools, though true 'ownership' is a little blurred. Regardless, Panels uses this plugin to interact with Stylaizer in order to allow the creation of style plugins in the UI.</dd> +<dd>This plugin is probably of interest only to module developers; site builders can safely skip it.</dd> +<dt><a href="topic:ctools/context-context">Context plugins</a></dt> +<dd><em>Owned by CTools.</em></dd> +<dd>Context plugins are abstracted wrappers around bits of data - a node, user, or taxonomy term are easy examples. Panels uses context plugins so that it can work with all these different bits of data without caring about the details of the datastructure itself. Context can be a confusing concept, and you can learn more in the <a href="topic:ctools/context">CTools help</a>.</dd> +<dd>Note that <a href="topic:ctools/context-arguments">argument</a> and <a href="topic:ctools/context-relationships">relationship</a> plugins are technically also used by Panels, but because they're really means for creating more context, they don't get separate entries in this list.</dd> +<dt><a href="topic:ctools/plugins-content">Content Type plugins</a></dt> +<dd><em>Owned by CTools: can utilize context.</em></dd> +<dd>At the heart of the Panels rendering process, content type plugins define the rendering logic for every pane. Offering Panels a renderable chunk from your module means defining one of these. For those accustomed to the block system, they can be thought of as a more verbose block definition, contained neatly inside a single plugin.</dd> +<dd>Content type plugins rely on context to provide them with source data, when necessary; this makes content plugins nice and portable.</dd> +<dt><a href="topic:ctools/context-access">Access plugins</a></dt> +<dd><em>Owned by CTools: can utilize context.</em></dd> +<dd>Access plugins are essentially portable access checking logic, responsible for answering "Yes" or "No" given some contextual data. Panels uses these to define 'visibility rules' on individual panes. The other place these are commonly seen is in defining 'Selection rules' on Page Manager variants.</dd> +<dd>If your module introduces new permissioning concepts or access logic (NOT a basic hook_perm() implementation), you may want to consider also encapsulating that logic in one or more of these plugins. For example, Organic Groups might implement an access plugin to allow/deny based on group membership, or the Date module might implement allow/deny logic based on request time.</dd> +<dt><a href="topic:panels/plugins-cache">Cache plugins</a></dt> +<dd><em>Owned by Panels; should utilize context.</em></dd> +<dd>Panels cache plugins define caching strategies that can be applied to individual panes, or to whole displays. Caching plugins must deal with two basic issues: the cache backend to use for reading/writing, and TTL-managing strategies.</dd> +<dd>TTL strategies can (and should) integrate heavily with the context, as that is where the real differential benefit of Panels-based caching is vs. standard core caching.</dd> +<dt><a href="topic:panels/plugins-renderers">Display Renderers</a></dt> +<dd><em>Owned by Panels: utilizes everything else.</em></dd> +<dd>In the simplest terms, display renderers take a fully-loaded panels_display object and render it. They are very complex, powerful plugins - one could use them to cause Panels to bypass every single other plugin in this list. Fortunately, there is virtually no circumstance under which one would need to implement these plugins in the process of building a single site; only contrib developers working on highly complex use cases are likely to ever need them.</dd> +<dd>In short, each display renderer plugin <strong>is</strong> a self-contained Panels rendering engine. If you want to grok the Panels rendering system, study these.</dd> +</dl> + + +<h2>Panels-based Applications</h2> +<p>At its core, Panels is a rendering engine with no UI (though it does provide common elements for reuse in admin UIs). So if you're working with Panels via the web UI, it means you're working with a Panels application. The three that ship with this version of Panels are Mini Panels, Panel Nodes, and the integration with CTools' Page Manager.</p> +<p>Panels also implements a task_handler plugin, which is owned by Page Manager in CTools. Task handlers aren't strictly a part of Panels' rendering system itself though (strictly speaking, they wrap it), so we won't cover them here.</p> \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/help/display.html b/drupal/sites/default/boinc/modules/contrib/panels/help/display.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/panels/help/panels.help.ini b/drupal/sites/default/boinc/modules/contrib/panels/help/panels.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..cc0ea392e0c154ccdd3b5c5c381d3a125018b649 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/help/panels.help.ini @@ -0,0 +1,74 @@ +[advanced help settings] +line break = TRUE + +[glossary] +title = Panels glossary of terms +weight = 100 + +[about] +title = About Panels +weight = -100 + +[common-tasks] +title = Accomplishing common tasks in Panels +weight = -50 + +[tutorials] +title = Panels tutorials and how-tos +weight = -30 + +[tutorial-landing] +title = Creating a simple landing page +parent = tutorials + +[tutorial-node] +title = Styling a node page +parent = tutorials + +[tutorial-vocabulary] +title = Styling a vocabulary +parent = tutorials + +[apps] +title = Panels-based applications +parent = api + +[panels-pages] +title = Panel pages, via Page Manager +parent = apps + +[panels-mini] +title = Mini panels +parent = apps + +[panels-node] +title = Panel nodes +parent = apps + +[api] +title = Working with the Panels API +weight = 50 + +[render-api] +title = Panels plugins +parent = api + +[plugins-layout] +title = Layout plugins +parent = render-api +weight = -10 + +[plugins-style] +title = Style plugins +parent = render-api +weight = -7 + +[plugins-cache] +title = Cache plugins +parent = render-api +weight = -4 + +[plugins-renderers] +title = Display Renderer plugins +parent = render-api +weight = -1 \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/help/plugins-layout.html b/drupal/sites/default/boinc/modules/contrib/panels/help/plugins-layout.html new file mode 100644 index 0000000000000000000000000000000000000000..45051b2d305f32a64336e33d3f71e747c518eebb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/help/plugins-layout.html @@ -0,0 +1,78 @@ +<h2>Getting Started:</h2> +<p>Layout plugins are one of the simplest and most powerful sections of the panels api. There are two different ways that a layout can be implemented via panels. Panels supports both module and theme implementations of panels. The module implementation requires that hook_ctools_plugin_directory define the directory in which your layout plugins exist. (This same hook defines the directory for all panels plugins) Alternately, if you intend on implementing a layout in a theme this can be done primary through the theme's info file. The CTools help does a great job of actually explaining this portion of the API <a href="topic:ctools/plugins-implementing">ctools: plugins</a>.</p> + +<p>CTools explains even the layout hooks a little in its example, but we'll recap quickly and expand on this information. As ctools explains, the actual plugin file must be named with care as it will directly affect your naming scheme for the hook within it. This is really no different from any other hook within drupal except that we'll be using multiple replacements in this case. The function we're looking to implement is an instance of: +<code>function YOURMODULE_PLUGINNAME_OWNERMODULE_PLUGINTYPE()</code> +In our case we already know that the function will be: +<code>function YOURMODULE_PLUGINNAME_panels_layouts()</code> +This is because the plugin type we're working with is a layout, and the module that implements these layouts is the panels module. For the rest of the naming scheme "YOURMODULE" will be replaced with either the name of your module that implements this layout, or the name of the theme, and "PLUGINNAME" will be replaced with whatever the name of the plugin file is. For purposes of this example our module name us going to be "layout_sample" and our plugin will be "first_layout".</p> + +<h2>Directory Structure:</h2> +<p>We're going to assume that you've laid your directory structure out very similarly to how panels does it. Something like this is rather likely: +<pre>layout_sample + layout_sample.info + layout_sample.module + plugins + layouts + first_layout + first_layout.css + first_layout.inc + first_layout.png + layout-sample-first-layout.tpl.php</pre> +The name of our .inc file is going to be the key to the entire layout plugin.</p> + +<h2>The .inc File:</h2> +<p>We will start with the first_layout.inc file as it's the most important file we're dealing with here. First_layout.inc will look similar to the following: +<pre> + $plugin = array( + 'title' => t('First Layout'), + 'icon' => 'first_layout.png', + 'theme' => 'layout_sample_first_layout', + 'css' => 'first_layout.css', + 'panels' => array( + 'main' => t('Main region'), + 'right' => t('Right region'), + ), + ); +</pre> +The include file defines all the other files that our layout will utilize in order to be truly useful. The array is fairly self explanitory but for the sake of specificity: +<ol> +<li><strong>Title:</strong><br />The title of our layout. (Utilized within the panels administration screens)</li> +<li><strong>Icon:</strong><br />The graphical representation of our layout. (Utilized within the panels administration screens)</li> +<li><strong>Theme:</strong><br />The template file of our layout. (Sharp eyed readers will note that the theme definition utilizes underscores instead of dashes, and does not have ".tpl.php" after it. This is refering to the layout-sample-first-layout.tpl.php file all the same, it is simply how the naming convention works. Utilize dashes in the tpl file name and underscores when refering to it in your include file.)</li> +<li><strong>CSS:</strong><br />The css file to be utilized for our layout. (Utilized within the panels administration screens, AND when viewing the actual panel itself.)</li> +<li><strong>Panels:</strong><br />Defines all the various regions within your panel. This will be further utilized within our tpl.php file.</li> +</ol> +There are many additional properties that can be added to the include file. For purposes of this document we'll also make mention of the 'admin css' property. 'Admin css' is especially useful when utilizing a fixed width layout with fixed with panel regions. This can break under most administrative circumstances, and panels provides you with the ability to give an additional css layout for the administrative section. It's a simple nicety and looks like this: +<pre> + $plugin = array( + 'title' => t('First Layout'), + 'icon' => 'first_layout.png', + 'theme' => 'layout_sample_first_layout', + 'css' => 'first_layout.css', + 'admin css' => 'first_layout_admin.css', + 'panels' => array( + 'main' => t('Main region'), + 'right' => t('Right region'), + ), + ); +</pre> +</p> + +<h2>The tpl.php File:</h2> +<p>The tpl.php file is very similar to any other template file within drupal. The difference here is that we're being passed an array of regions through $content, and we also have a css id available to us for the entire panel in the form of $css_id. The template is very straight forward and will look similar to the following: +<pre><div class="panel-display panel-stacked-twothirds-onethird clear-block" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <div class="panel-panel panel-col-first panel-region-main"> + <div class="inside"><?php print $content['main']; ?></div> + </div> + + <div class="panel-panel panel-col-last panel-region-right"> + <div class="inside"><?php print $content['right']; ?></div> + </div> +</div> +</pre> +This is simply an example of what the html could look like. You can alter an update this html to fit your own needs. +</p> + +<h2>The Other Files:</h2> +<p>The css and png files are as simple as any other css or png file you've ever utilized. Panels provides some images for its graphical representations of its layouts. I would heavily encourage you to modify these to suit your needs. The CSS files (admin and non) will be included at the appropriate times. Simply set them up to fit your purposes. If you're utilizing fixed width panel regions it's probably smart to provide an admin css file as well with your panel layout.</p> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/help/plugins-style.html b/drupal/sites/default/boinc/modules/contrib/panels/help/plugins-style.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/arrow-active.png b/drupal/sites/default/boinc/modules/contrib/panels/images/arrow-active.png new file mode 100644 index 0000000000000000000000000000000000000000..3bbd3c27f29f9a1781276a2ae8faa7afd5d2d36e Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/arrow-active.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/arrow-down-light.png b/drupal/sites/default/boinc/modules/contrib/panels/images/arrow-down-light.png new file mode 100644 index 0000000000000000000000000000000000000000..f011ac69211aa7800f21914bdf780d8f1f589283 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/arrow-down-light.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/bg-content-modal.png b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-content-modal.png new file mode 100644 index 0000000000000000000000000000000000000000..600d074c37e7adc1749bfae322e26f87f0d2507b Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-content-modal.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-dark.png b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..1be36f2d3d89417f3f725546e5ee165b238dfdf7 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-dark.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-light.png b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-light.png new file mode 100644 index 0000000000000000000000000000000000000000..ad7167b976c2c9841304120c090a7e942eb0a643 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-light.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-medium.png b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-medium.png new file mode 100644 index 0000000000000000000000000000000000000000..e4b39fe93c4ef9a16e6077437be69bfdfd8e46a4 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-medium.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-white-lrg.png b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-white-lrg.png new file mode 100644 index 0000000000000000000000000000000000000000..842e5f7ff54658442e4449ca7aa1c3d419518e1c Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/bg-shade-white-lrg.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/blank.gif b/drupal/sites/default/boinc/modules/contrib/panels/images/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..75b945d2553848b8b6f41fe5e24599c0687b8472 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/blank.gif differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/close.gif b/drupal/sites/default/boinc/modules/contrib/panels/images/close.gif new file mode 100644 index 0000000000000000000000000000000000000000..46891b0c0d4871eb17b8e71690f42c6eae76bd7c Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/close.gif differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/delete.png b/drupal/sites/default/boinc/modules/contrib/panels/images/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..f790555163b1abcad7e350282a47ef8f77d8ec4a Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/delete.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/go-down.png b/drupal/sites/default/boinc/modules/contrib/panels/images/go-down.png new file mode 100644 index 0000000000000000000000000000000000000000..c2def1a3124f8aa309bdcd7a0b3aef6c191b4616 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/go-down.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/go-right.png b/drupal/sites/default/boinc/modules/contrib/panels/images/go-right.png new file mode 100644 index 0000000000000000000000000000000000000000..dd6058c8652f419bbef9f6c3259c080bcf6ab364 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/go-right.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/go-up.png b/drupal/sites/default/boinc/modules/contrib/panels/images/go-up.png new file mode 100644 index 0000000000000000000000000000000000000000..a52c7dcb66d2be7169372a149058892482eccc6c Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/go-up.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/icon-addcontent.png b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-addcontent.png new file mode 100644 index 0000000000000000000000000000000000000000..788d01ff2574383caf22d8e553949fe3c4b95468 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-addcontent.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/icon-cache.png b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-cache.png new file mode 100644 index 0000000000000000000000000000000000000000..3e6f46b3fb5586a57d939939536f484a67dcda19 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-cache.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/icon-configure.png b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-configure.png new file mode 100644 index 0000000000000000000000000000000000000000..e23d67cc04b84880d0437e23ffcba837d2dc4121 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-configure.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/icon-delete.png b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0cf695b0cac487efecfd7eae66e7492a2ba306 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-delete.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/icon-draggable.png b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-draggable.png new file mode 100644 index 0000000000000000000000000000000000000000..dba8b67cdf37714c933bc9514cfdf5e35df89fb3 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-draggable.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/icon-hidepane.png b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-hidepane.png new file mode 100644 index 0000000000000000000000000000000000000000..851698056e69dd3058fe1cc0456064ebb49909be Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-hidepane.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/icon-showpane.png b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-showpane.png new file mode 100644 index 0000000000000000000000000000000000000000..7549dd94d646ef74cb640beeeb911bfec9895bf5 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/icon-showpane.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/no-icon.png b/drupal/sites/default/boinc/modules/contrib/panels/images/no-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..30584e6f2540ad49dac98060d1a7f8a5af1b27b7 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/no-icon.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/portlet-collapsed.png b/drupal/sites/default/boinc/modules/contrib/panels/images/portlet-collapsed.png new file mode 100644 index 0000000000000000000000000000000000000000..95a214a6e6d17fee2f098804997f3826ffc9d4ca Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/portlet-collapsed.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/portlet-expanded.png b/drupal/sites/default/boinc/modules/contrib/panels/images/portlet-expanded.png new file mode 100644 index 0000000000000000000000000000000000000000..46f39ecb351cff65243fa9a614a69d039e1302a5 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/portlet-expanded.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-1.jpg b/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..72043574bbc5cc56842f00ea90b2b92dd1f45edc Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-1.jpg differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-2.jpg b/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..80203d82a0b96c769242781a6db848983d53d20d Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-2.jpg differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-3.jpg b/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2d6ce09b28447500b57d1ef5d08cb37d58917269 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-3.jpg differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-4.jpg b/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf7d77db7af8f5364bc8aed4be3e3d5297e45034 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/screenshot-4.jpg differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/sky.png b/drupal/sites/default/boinc/modules/contrib/panels/images/sky.png new file mode 100644 index 0000000000000000000000000000000000000000..35b9380f434d9bdff12765bc77ace195dc260764 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/sky.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/sprite.png b/drupal/sites/default/boinc/modules/contrib/panels/images/sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..fe74899e2b1f8ea62292b8b8de79c59f6eb07a71 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/sprite.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/throbber.gif b/drupal/sites/default/boinc/modules/contrib/panels/images/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..8a084b8447d506e9b655ad52405cbf7a73034550 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/throbber.gif differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/images/user-trash.png b/drupal/sites/default/boinc/modules/contrib/panels/images/user-trash.png new file mode 100644 index 0000000000000000000000000000000000000000..71e4c46265aaf28ac59b0aaaa8d90d450d1af25d Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/images/user-trash.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/callbacks.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/callbacks.inc new file mode 100644 index 0000000000000000000000000000000000000000..00a4509c802c0b3a74b9091de0d25972ac7f5646 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/callbacks.inc @@ -0,0 +1,188 @@ +<?php +/** + * @file callbacks.inc + * Minor menu callbacks for Panels helpers. + */ + +/** + * A central administrative page for Panels. + */ +function panels_admin_page() { + return theme('panels_dashboard'); +} + +function panels_dashboard_final_blocks(&$vars) { + // Add in links for missing modules that we still want to mention: + if (empty($vars['links']['page_manager'])) { + $vars['links']['page_manager'] = array( + 'weight' => -100, + 'title' => t('Panel page'), + 'description' => '<em>' . t('You must activate the page manager module for this functionality.') . '</em>', + ); + } + if (empty($vars['links']['panels_mini'])) { + $vars['links']['panels_mini'] = array( + 'title' => t('Mini panel'), + 'description' => '<em>' . t('You must activate the Mini panels module for this functionality.') . '</em>', + ); + } + if (empty($vars['links']['panels_node'])) { + $vars['links']['panels_mini'] = array( + 'title' => t('Panel node'), + 'description' => '<em>' . t('You must activate the panel node module for this functionality.') . '</em>', + ); + } +} + +/** + * Implementation of hook_panels_dashboard_blocks(). + * + * Adds page information to the Panels dashboard. + */ +function panels_panels_dashboard_blocks(&$vars) { + $vars['links']['panels_layout'] = array( + 'title' => l(t('Custom layout'), 'admin/build/panels/layouts/add'), + 'description' => t('Custom layouts can add more, site-specific layouts that you can use in your panels.'), + ); + + // Load all mini panels and their displays. + ctools_include('export'); + $items = ctools_export_crud_load_all('panels_layout'); + $count = 0; + $rows = array(); + + foreach ($items as $item) { + $rows[] = array( + check_plain($item->admin_title), + array( + 'data' => l(t('Edit'), "admin/build/panels/layouts/list/$item->name/edit"), + 'class' => 'links', + ), + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + + if ($rows) { + $content = theme('table', array(), $rows, array('class' => 'panels-manage')); + } + else { + $content = '<p>' . t('There are no custom layouts.') . '</p>'; + } + + $vars['blocks']['panels_layout'] = array( + 'title' => t('Manage custom layouts'), + 'link' => l(t('Go to list'), 'admin/build/panels/layouts'), + 'content' => $content, + 'class' => 'dashboard-layouts', + 'section' => 'right', + ); +} + +function template_preprocess_panels_dashboard(&$vars) { + ctools_add_css('panels-dashboard', 'panels'); + ctools_include('plugins'); + + $vars['image_path'] = ctools_image_path('', 'panels'); + + $vars['links'] = array(); + $vars['blocks'] = array(); + + foreach (module_implements('panels_dashboard_blocks') as $module) { + $function = $module . '_panels_dashboard_blocks'; + $function($vars); + } + + // Add in any default links for modules that are not active + panels_dashboard_final_blocks($vars); + + // If page manager module is enabled, add a very low eight block to + // list the page wizards. + if (module_exists('page_manager')) { + $vars['blocks']['wizards'] = array( + 'weight' => -101, + 'section' => 'right', + 'title' => t('Page wizards'), + 'content' => '', + 'class' => 'dashboard-wizards', + ); + + ctools_include('page-wizard'); + $plugins = page_manager_get_page_wizards(); + uasort($plugins, 'ctools_plugin_sort'); + + foreach ($plugins as $id => $plugin) { + if (isset($plugin['type']) && $plugin['type'] == 'panels') { + $link = array( + 'title' => l($plugin['title'], 'admin/build/pages/wizard/' . $id), + 'description' => $plugin['description'], + ); + + $vars['blocks']['wizards']['content'] .= theme('panels_dashboard_link', $link); + } + } + + } + + uasort($vars['links'], 'ctools_plugin_sort'); + + $vars['blocks']['links'] = array( + 'weight' => -100, + 'section' => 'left', + 'title' => t('Create new') . '...', + 'content' => '', + 'class' => 'dashboard-create', + ); + + // Turn the links into a block + foreach ($vars['links'] as $link) { + $vars['blocks']['links']['content'] .= theme('panels_dashboard_link', $link); + } + + uasort($vars['blocks'], 'ctools_plugin_sort'); + + $vars['left'] = ''; + $vars['right'] = ''; + + // Render all the blocks + foreach ($vars['blocks'] as $block) { + $section = !empty($block['section']) ? $block['section'] : 'left'; + $vars[$section] .= theme('panels_dashboard_block', $block); + } +} + +function panels_admin_settings_page() { + $form = array(); + if (module_exists('page_manager')) { + foreach (page_manager_get_tasks() as $task) { + if ($function = ctools_plugin_get_function($task, 'admin settings')) { + $function($form); + } + } + } + + ctools_include('content'); + foreach (ctools_get_content_types() as $content) { + if ($function = ctools_plugin_get_function($content, 'admin settings')) { + $function($form); + } + } + + if (empty($form)) { + return array('#value' => t('There are currently no settings to change, but additional plugins or modules may provide them in the future.')); + } + + return system_settings_form($form); +} + +/** + * Settings for panel contexts created by the page manager. + */ +function panels_admin_panel_context_page() { + ctools_include('common', 'panels'); + return drupal_get_form('panels_common_settings', 'panels_page'); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/common.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/common.inc new file mode 100644 index 0000000000000000000000000000000000000000..16ed3fdfce1e8dfdf200ec8198e9493358f1c554 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/common.inc @@ -0,0 +1,573 @@ +<?php + + +/** + * @file + * Functions used by more than one panels client module. + */ + +/** + * Class definition for the allowed layouts governing structure. + * + * @ingroup mainapi + * + * This class is designed to handle panels allowed layouts data from start to finish, and sees + * action at two times:\n + * - When a client module wants to generate a form allowing an admin to create or edit a set + * of allowed layouts. In this case, either a new panels_allowed_layouts object is created + * or one is retrieved from storage and panels_allowed_layouts::set_allowed() is called to + * generate the allowed layouts form. \n + * - When a client module is calling panels_edit_layout(), a saved instantiation of this object + * can be called up and passed in to the fourth parameter, and only the allowed layouts saved + * in that object will be displayed on the form. \n + * Because the panels API does not impose a data structure on the allowed_layouts data, client + * modules can create as many of these objects as they want, and organize them around any concept: + * node types, date published, author roles...anything. + * + * To call the settings form, instantiate this class - or, if your client module's needs are + * heavy-duty, extend this class and instantiate your subclass - assign values to any relevant + * desired members, and call panels_allowed_layouts::set_allowed(). See the documentation on + * that method for a sample implementation. + * + * Note that when unserializing saved tokens of this class, you must + * run panels_load_include('common') before unserializing in order to ensure + * that the object is properly loaded. + * + * Client modules extending this class should implement a save() method and use it for + * their custom data storage routine. You'll need to rewrite other class methods if + * you choose to go another route. + * + * @see panels_edit_layout() + * @see _panels_edit_layout() + * + */ +class panels_allowed_layouts { + + /** + * Specifies whether newly-added layouts (as in, new .inc files) should be automatically + * allowed (TRUE) or disallowed (FALSE) for $this. Defaults to TRUE, which is more + * permissive but less of an administrative hassle if/when you add new layouts. Note + * that this parameter will be derived from $allowed_layouts if a value is passed in. + */ + var $allow_new = TRUE; + + /** + * Optional member. If provided, the Panels API will generate a drupal variable using + * variable_set($module_name . 'allowed_layouts', serialize($this)), thereby handling the + * storage of this object entirely within the Panels API. This object will be + * called and rebuilt by panels_edit_layout() if the same $module_name string is passed in + * for the $allowed_types parameter. \n + * This is primarily intended for convenience - client modules doing heavy-duty implementations + * of the Panels API will probably want to create their own storage method. + * @see panels_edit_layout() + */ + var $module_name = NULL; + + /** + * An associative array of all available layouts, keyed by layout name (as defined + * in the corresponding layout plugin definition), with value = 1 if the layout is + * allowed, and value = 0 if the layout is not allowed. + * Calling array_filter(panels_allowed_layouts::$allowed_layout_settings) will return an associative array + * containing only the allowed layouts, and wrapping that in array_keys() will + * return an indexed version of that array. + */ + var $allowed_layout_settings = array(); + + /** + * Hack-imitation of D6's $form_state. Used by the panels_common_set_allowed_types() + * form to indicate whether the returned value is in its 'render', 'failed-validate', + * or 'submit' stage. + */ + var $form_state; + + /** + * Constructor function; loads the $allowed_layout_settings array with initial values according + * to $start_allowed + * + * @param bool $start_allowed + * $start_allowed determines whether all available layouts will be marked + * as allowed or not allowed on the initial call to panels_allowed_layouts::set_allowed() + * + */ + function panels_allowed_layouts($start_allowed = TRUE) { + // TODO would be nice if there was a way to just fetch the names easily + foreach ($this->list_layouts() as $layout_name) { + $this->allowed_layout_settings[$layout_name] = $start_allowed ? 1 : 0; + } + } + + /** + * Manage panels_common_set_allowed_layouts(), the FAPI code for selecting allowed layouts. + * + * MAKE SURE to set panels_allowed_layouts::allow_new before calling this method. If you want the panels API + * to handle saving these allowed layout settings, panels_allowed_layouts::module_name must also be set. + * + * Below is a sample implementation; refer to the rest of the class documentation to understand all the + * specific pieces. Values that are intended to be replaced are wrapped with <>. + * + * \n @code + * function docdemo_allowed_layouts() { + * ctools_include('common', 'panels'); + * if (!is_a($allowed_layouts = unserialize(variable_get('panels_common_allowed_layouts', serialize(''))), 'panels_allowed_layouts')) { + * $allowed_layouts = new panels_allowed_layouts(); + * $allowed_layouts->allow_new = TRUE; + * $allowed_layouts->module_name = '<client_module_name>'; + * } + * $result = $allowed_layouts->set_allowed('<Desired client module form title>'); + * if (in_array($allowed_layouts->form_state, array('failed-validate', 'render'))) { + * return $result; + * } + * elseif ($allowed_layouts->form_state == 'submit') { + * drupal_goto('</path/to/desired/redirect>'); + * } + * } + * @endcode \n + * + * If $allowed_layouts->form_state == 'failed-validate' || 'render', then you'll need to return + * $result as it contains the structured form HTML generated by drupal_render_form() and is ready + * to be passed through index.php's call to theme('page', ...). + * + * However, if $allowed_layouts->form_state == 'submit', then the form has been submitted and we should + * react. It's really up to your client module how you handle the rest; panels_allowed_layouts::save() (or + * panels_allowed_layouts::api_save(), if that's the route you're going) will have already been called, + * so if those methods handle your save routine, then all there is left to do is handle redirects, if you + * want. The current implementation of the allowed layouts form currently never redirects, so it's up to + * you to control where the user ends up next. + * + * @param string $title + * Used to set the title of the allowed layouts form. If no value is given, defaults to + * 'Panels: Allowed Layouts'. + * + * @return mixed $result + * - On the first passthrough when the form is being rendered, $result is the form's structured + * HTML, ready to be pushed to the screen with a call to theme('page', ...). + * - A successful second passthrough indicates a successful submit, and + * $result === panels_allowed_layouts::allowed_layout_settings. Returning it is simply for convenience. + */ + function set_allowed($title = 'Panels: Allowed Layouts') { + $this->sync_with_available(); + $form_id = 'panels_common_set_allowed_layouts'; + // TODO switch to drupal_build_form(); need to pass by ref + $form = drupal_retrieve_form($form_id, $this, $title); + + if ($result = drupal_process_form($form_id, $form)) { + // successful submit + $this->form_state = 'submit'; + return $result; + } + $this->form_state = isset($_POST['op']) ? 'failed-validate' : 'render'; + $result = drupal_render_form($form_id, $form); + return $result; + } + + /** + * Checks for newly-added layouts and deleted layouts. If any are found, updates panels_allowed_layouts::allowed_layout_settings; + * new additions are made according to panels_allowed_layouts::allow_new, while deletions are unset(). + * + * Note that any changes made by this function are not saved in any permanent location. + */ + function sync_with_available() { + $layouts = $this->list_layouts(); + foreach (array_diff($layouts, array_keys($this->allowed_layout_settings)) as $new_layout) { + $this->allowed_layout_settings[$new_layout] = $this->allow_new ? 1 : 0; + } + foreach (array_diff(array_keys($this->allowed_layout_settings), $layouts) as $deleted_layout) { + unset($this->allowed_layout_settings[$deleted_layout]); + } + } + + /** + * Use panels_allowed_layouts::module_name to generate a variable for variable_set(), in which + * a serialized version of $this will be stored. + * + * Does nothing if panels_allowed_layouts::module_name is not set. + * + * IMPORTANT NOTE: if you use variable_get() in a custom client module save() method, you MUST + * wrap $this in serialize(), then unserialize() what you get from variable_get(). Failure to + * do so will result in an incomplete object. The following code will work: + * @code + * $allowed_layouts = unserialize(variable_get('your_variable_name', serialize('')); + * @endcode + * + * If you don't serialize the second parameter of variable_get() and the variable name you provide + * can't be found, an E_STRICT warning will be generated for trying to unserialize an entity + * that has not been serialized. + * + */ + function save() { + if (!is_null($this->module_name)) { + variable_set($this->module_name . "_allowed_layouts", serialize($this)); + } + } + + /** + * Snag a list of the current layouts for internal use. + * + * Data is not saved in a class member in order to ensure that it's + * fresh. + * + * @return array $layouts + * An indexed array of the system names for all currently available layouts. + */ + function list_layouts() { + static $layouts = array(); + if (empty($layouts)) { + ctools_include('plugins', 'panels'); + $layouts = array_keys(panels_get_layouts()); + } + return $layouts; + } +} + +/** + * A common settings page for Panels modules, because this code is relevant to + * any modules that don't already have special requirements. + */ +function panels_common_settings(&$form_state, $module_name = 'panels_common') { + ctools_include('plugins', 'panels'); + ctools_include('content'); + $content_types = ctools_get_content_types(); + $skip = FALSE; + + $default_types = variable_get($module_name . '_default', NULL); + if (!isset($default_types)) { + $default_types = array('other' => TRUE); + $skip = TRUE; + } + + foreach ($content_types as $id => $info) { + if (empty($info['single'])) { + $default_options[$id] = t('New @s', array('@s' => $info['title'])); + if ($skip) { + $default_types[$id] = TRUE; + } + } + } + + $default_options['other'] = t('New content of other types'); + $form['panels_common_default'] = array( + '#type' => 'checkboxes', + '#title' => t('New content behavior'), + '#description' => t('Select the default behavior of new content added to the system. If checked, new content will automatically be immediately available to be added to Panels pages. If not checked, new content will not be available until specifically allowed here.'), + '#options' => $default_options, + '#default_value' => array_keys(array_filter($default_types)), + ); + + $form_state['skip'] = $skip; + if ($skip) { + $form['markup'] = array('#value' => t('<p>Click Submit to be presented with a complete list of available content types set to the defaults you selected.</p>')); + } + else { + // Rebuild the entire list, setting appropriately from defaults. Give + // each type its own checkboxes set unless it's 'single' in which + // case it can go into our fake other set. + $available_content_types = ctools_content_get_all_types(); + $allowed_content_types = variable_get($module_name . '_allowed_types', array()); + + foreach ($available_content_types as $id => $types) { + foreach ($types as $type => $info) { + $key = $id . '-' . $type; + $checkboxes = empty($content_types[$id]['single']) ? $id : 'other'; + $options[$checkboxes][$key] = $info['title']; + if (!isset($allowed_content_types[$key])) { + $allowed[$checkboxes][$key] = isset($default_types[$id]) ? $default_types[$id] : $default_types['other']; + } + else { + $allowed[$checkboxes][$key] = $allowed_content_types[$key]; + } + } + } + + $form['content_types'] = array( + '#tree' => TRUE, + '#prefix' => '<div class="clear-block">', + '#suffix' => '</div>', + ); + // cheat a bit + $content_types['other'] = array('title' => t('Other'), 'weight' => 10); + foreach ($content_types as $id => $info) { + if (isset($allowed[$id])) { + $form['content_types'][$id] = array( + '#prefix' => '<div class="panels-page-type-container">', + '#suffix' => '</div>', + '#type' => 'checkboxes', + '#title' => t('Allowed @s content', array('@s' => $info['title'])), + '#options' => $options[$id], + '#default_value' => array_keys(array_filter($allowed[$id])), + '#checkall' => TRUE, + ); + } + } + } + + panels_common_allowed_layouts_form($form, $form_state, $module_name); + + $form['module_name'] = array( + '#type' => 'value', + '#value' => $module_name, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + ctools_add_css('panels_page', 'panels'); + return $form; +} + +/** + * Submit hook for panels_common_settings + */ +function panels_common_settings_validate($form, &$form_state) { + panels_common_allowed_layouts_form_validate($form, $form_state); +} + +/** + * Submit hook for panels_common_settings + */ +function panels_common_settings_submit($form, &$form_state) { + panels_common_allowed_layouts_form_submit($form, $form_state); + $module_name = $form_state['values']['module_name']; + variable_set($module_name . '_default', $form_state['values']['panels_common_default']); + if (!$form_state['skip']) { + // merge the broken apart array neatly back together + variable_set($module_name . '_allowed_types', call_user_func_array('array_merge', $form_state['values']['content_types'])); + } + drupal_set_message(t('Your changes have been saved.')); +} + +/** + * Based upon the settings, get the allowed types for this node. + */ +function panels_common_get_allowed_types($module, $contexts = array(), $has_content = FALSE, $default_defaults = array(), $default_allowed_types = array()) { + // Get a list of all types that are available + + $default_types = variable_get($module . '_default', $default_defaults); + $allowed_types = variable_get($module . '_allowed_types', $default_allowed_types); + + // By default, if they haven't gone and done the initial setup here, + // let all 'other' types (which will be all types) be available. + if (!isset($default_types['other'])) { + $default_types['other'] = TRUE; + } + + ctools_include('content'); + $content_types = ctools_content_get_available_types($contexts, $has_content, $allowed_types, $default_types); + + return $content_types; +} + +/** + * The FAPI code for generating an 'allowed layouts' selection form. + * + * NOTE: Because the Panels API does not guarantee a particular method of storing the data on allowed layouts, + * it is not_possible for the Panels API to implement any checks that determine whether reductions in + * the set of allowed layouts conflict with pre-existing layout selections. $displays in that category + * will continue to function with their current layout as normal until the user/owner/admin attempts + * to change layouts on that display, at which point they will have to select from the new set of + * allowed layouts. If this is not the desired behavior for your client module, it's up to you to + * write a validation routine that determines what should be done with conflicting layouts. + * + * Remember that changing layouts where panes have already been created can result in data loss; + * consult panels_change_layout() to see how the Panels API handles that process. Running + * drupal_execute('panels_change_layout', ...) is one possible starting point. + * + * @ingroup forms + * + * @param array $allowed_layouts + * The set of allowed layouts that should be used as the default values + * for this form. If none is provided, then by default no layouts will be restricted. + */ +function panels_common_allowed_layouts_form(&$form, &$form_state, $module_name) { + // Fetch our allowed layouts from variables. + $allowed_layouts = panels_common_get_allowed_layout_object($module_name); + + $layouts = panels_get_layouts(); + foreach ($layouts as $id => $layout) { + $options[$id] = panels_print_layout_icon($id, $layout, check_plain($layout['title'])); + } + + $form_state['allowed_layouts'] = &$allowed_layouts; + + ctools_add_js('layout', 'panels'); + $form['layouts'] = array( + '#type' => 'checkboxes', + '#title' => t('Select allowed layouts'), + '#options' => $options, + '#description' => t('Check the boxes for all layouts you want to allow users choose from when picking a layout. You must allow at least one layout.'), + '#default_value' => array_keys(array_filter($allowed_layouts->allowed_layout_settings)), + '#prefix' => '<div class="clear-block panels-layouts-checkboxes">', + '#suffix' => '</div>', + '#checkall' => TRUE, + ); + + return $form; +} + +function panels_common_allowed_layouts_form_validate($form, &$form_state) { + $selected = array_filter($form_state['values']['layouts']); + if (empty($selected)) { + form_set_error('layouts', 'You must choose at least one layout to allow.'); + } +} + +function panels_common_allowed_layouts_form_submit($form, &$form_state) { + foreach ($form_state['values']['layouts'] as $layout => $setting) { + $form_state['allowed_layouts']->allowed_layout_settings[$layout] = (bool) $setting; + } + $form_state['allowed_layouts']->save(); +} + +/** + * Get the allowed layout object for the given module. + */ +function panels_common_get_allowed_layout_object($module_name) { + $allowed_layouts = unserialize(variable_get($module_name . "_allowed_layouts", serialize(''))); + + // if no parameter was provided, or the variable_get failed + if (!$allowed_layouts) { + // still no dice. simply creates a dummy version where all layouts + // are allowed. + $allowed_layouts = new panels_allowed_layouts(); + $allowed_layouts->allow_new = TRUE; + $allowed_layouts->module_name = $module_name; + } + + // sanitize allowed layout listing; this is redundant if the + // $allowed_layouts param was null, but the data is cached anyway + $allowed_layouts->sync_with_available(); + + return $allowed_layouts; +} + +/** + * Get the allowed layouts for the given module. + */ +function panels_common_get_allowed_layouts($module_name) { + $available_layouts = panels_get_layouts(); + if (empty($module_name)) { + return $available_layouts; + } + else if (is_object($module_name)) { + $allowed_layouts = $module_name; + } + else { + $allowed_layouts = panels_common_get_allowed_layout_object($module_name); + } + + $allowed = array_filter($allowed_layouts->allowed_layout_settings); + $order = array(); + foreach ($available_layouts as $name => $plugin) { + if (!empty($allowed[$name])) { + $order[$name] = $plugin['category'] . ':' . $plugin['title']; + } + } + + // Sort + $layouts = array(); + + asort($order); + foreach ($order as $name => $junk) { + $layouts[$name] = $available_layouts[$name]; + } + + return $layouts; +} + +/** + * Create a visible list of content in a display. + * Note that the contexts must be pre-loaded. + */ +function theme_panels_common_content_list($display) { + $layout = panels_get_layout($display->layout); + $content = '<dl class="content-list">'; + foreach (panels_get_regions($layout, $display) as $panel_id => $title) { + $content .= "<dt>$title</dt><dd>"; + if (!empty($display->panels[$panel_id])) { + $content .= '<ol>'; + foreach ($display->panels[$panel_id] as $pid) { + $content .= '<li>' . panels_get_pane_title($display->content[$pid], $display->context) . '</li>'; + } + $content .= '</ol>'; + } + else { + $content .= t('Empty'); + } + $content .= '</dd>'; + } + $content .= '</dl>'; + return $content; +} + +/** + * Print a selector of layouts, each linked to the next step. + * + * Most operations use radio buttons for selecting layouts, but some will + * give each layout as a link that goes to the next step. This function + * makes it easy to simply provide a list of allowed layouts and the base + * path. + * + * One limitation is that it will only append the layout name to the end, so + * if the actual layout name is needed in the middle, that can't happen. + * + * @return + * The rendered output. + */ +function panels_common_print_layout_links($layouts, $base_path, $link_options = array()) { + $output = ''; + + $categories = array(); + ctools_include('cleanstring'); + foreach ($layouts as $id => $layout) { + $category = ctools_cleanstring($layout['category']); + + $categories[$category] = $layout['category']; + $options[$category][$id] = panels_print_layout_link($id, $layout, $base_path . '/' . $id, $link_options); + } + + $form = array(); + $form['categories'] = array( + '#title' => t('Category'), + '#type' => 'select', + '#options' => $categories, + '#name' => 'categories', + '#id' => 'edit-categories', + '#value' => '', + '#parents' => array('categories'), + ); + + $output .= drupal_render($form); + + $output .= '<div class="panels-choose-layout panels-layouts-checkboxes clear-block">'; + + // We're doing these dependencies completely manualy, which is unusual, but + // the process code only supports doing them in a form. + // @todo modify dependent.inc to make this easier. + + $dependencies = array(); + foreach ($options as $category => $links) { + $dependencies['panels-layout-category-' . $category] = array( + 'values' => array('edit-categories' => array($category)), + 'num' => 1, + 'type' => 'hide', + ); + + $output .= '<div id="panels-layout-category-' . $category . '-wrapper">'; + $output .= '<div id="panels-layout-category-' . $category . '" class="form-checkboxes clear-block">'; + $output .= '<div class="panels-layouts-category">' . $categories[$category] . '</div>'; + + foreach ($links as $key => $link) { + $output .= $link; + } + $output .= '</div></div>'; + } + + $output .= '</div>'; + + ctools_add_js('dependent'); + $js['CTools']['dependent'] = $dependencies; + drupal_add_js($js, 'setting'); + + return $output; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/display-edit.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/display-edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..9db908a17830627cd8813ab2c527fe85246b08f9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/display-edit.inc @@ -0,0 +1,303 @@ +<?php + +/* + * @file + * Core Panels API include file containing various display-editing functions. + * This includes all the basic editing forms (content, layout, layout settings) + * as well as the ajax modal forms associated with them. + */ + + +/** + * Handle calling and processing of the form for editing display content. + * + * Helper function for panels_edit(). + * + * @see panels_edit() for details on the various behaviors of this function. + */ +function _panels_edit($display, $destination, $content_types, $title = FALSE) { + $did = $display->did; + if (!$did) { + $display->did = $did = 'new'; + } + + // Load the display being edited from cache, if possible. + if (!empty($_POST) && is_object($cache = panels_edit_cache_get($did))) { + $display = $cache->display; + } + else { + $cache = panels_edit_cache_get_default($display, $content_types, $title); + } + + // Get a renderer. + $renderer = panels_get_renderer_handler('editor', $display); + $renderer->cache = $cache; + + $output = $renderer->edit(); + if (is_object($output) && $destination) { + return panels_goto($destination); + } + return $output; +} + +/** + * Form definition for the panels display editor + * + * No validation function is necessary, as all 'validation' is handled + * either in the lead-up to form rendering (through the selection of + * specified content types) or by the validation functions specific to + * the ajax modals & content types. + * + * @ingroup forms + * @see panels_edit_display_submit() + */ +function panels_edit_display_form(&$form_state) { + $display = &$form_state['display']; + $renderer = &$form_state['renderer']; + + // Make sure there is a valid cache key. + $cache_key = isset($display->cache_key) ? $display->cache_key : $display->did; + $display->cache_key = $cache_key; + + // Annoyingly, theme doesn't have access to form_state so we have to do this. + $form['#display'] = $display; + + // The flexible layout maker wants to be able to edit a display without + // actually editing a display, so we provide this 'setting' to allow + // that to go away. + if (empty($form_state['no display settings'])) { + $links = $renderer->get_display_links(); + } + else { + $links = ''; + } + $form['hide']['display-settings'] = array( + '#value' => $links, + ); + + $form += panels_edit_display_settings_form($form_state); + + $form['panel'] = array('#tree' => TRUE); + $form['panel']['pane'] = array('#tree' => TRUE); + + $form['display'] = array( + '#value' => $renderer->render(), + ); + + foreach ($renderer->plugins['layout']['panels'] as $region_id => $title) { + // Make sure we at least have an empty array for all possible locations. + if (!isset($display->panels[$region_id])) { + $display->panels[$region_id] = array(); + } + + $form['panel']['pane'][$region_id] = array( + // Use 'hidden' instead of 'value' so the js can access it. + '#type' => 'hidden', + '#default_value' => implode(',', (array) $display->panels[$region_id]), + ); + } + + if (empty($form_state['no buttons'])) { + $form['buttons']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + '#id' => 'panels-dnd-save', + '#submit' => array('panels_edit_display_form_submit'), + '#save-display' => TRUE, + ); + $form['buttons']['cancel'] = array( + '#type' => 'submit', + '#value' => t('Cancel'), + ); + } + + // Build up the preview portion of the form, if necessary. + if (empty($form_state['no preview'])) { + $form['preview'] = array( + '#tree' => TRUE, + '#prefix' => '<h2>' . t('Live preview') . '</h2>' . '<div id="panels-live-preview">', + '#suffix' => '</div>', + ); + + ctools_context_replace_form($form['preview'], $display->context); + $form['preview']['button'] = array( + '#type' => 'submit', + '#value' => t('Preview'), + '#attributes' => array('class' => 'ctools-use-ajax'), + '#id' => 'panels-live-preview-button', + '#submit' => array('panels_edit_display_form_submit', 'panels_edit_display_form_preview'), + ); + } + + return $form; +} + +/** + * Handle form submission of the display content editor. + * + * This reads the location of the various panes from the form, which will + * have been modified from the ajax, rearranges them and then saves + * the display. + */ +function panels_edit_display_form_submit($form, &$form_state) { + $display = &$form_state['display']; + + $old_content = $display->content; + $display->content = array(); + + if (!empty($form_state['values']['panel']['pane'])) { + foreach ($form_state['values']['panel']['pane'] as $panel_id => $panes) { + $display->panels[$panel_id] = array(); + if ($panes) { + $pids = explode(',', $panes); + // need to filter the array, b/c passing it in a hidden field can generate trash + foreach (array_filter($pids) as $pid) { + if ($old_content[$pid]) { + $display->panels[$panel_id][] = $pid; + $old_content[$pid]->panel = $panel_id; + $display->content[$pid] = $old_content[$pid]; + } + } + } + } + } + + panels_edit_display_settings_form_submit($form, $form_state); +} + +/** + * Submission of the preview button. Render the preview and put it into + * the preview widget area. + */ +function panels_edit_display_form_preview(&$form, &$form_state) { + $display = &$form_state['display']; + ctools_include('ajax'); + + $display->context = ctools_context_replace_placeholders($display->context, $form_state['values']['preview']); + $display->skip_cache = TRUE; + $output = panels_render_display($display); + + // Add any extra CSS that some layouts may have added specifically for this. + if (!empty($display->add_css)) { + $output = "<style type=\"text/css\">\n$display->add_css</style>\n" . $output; + } + + $commands = array(); + $commands[] = array( + 'command' => 'panel_preview', + 'output' => $output, + ); + + ctools_ajax_render($commands); +} + + +/** + * Form for display settings. + */ +function panels_edit_display_settings_form(&$form_state) { + $form = array(); + $display = &$form_state['display']; + + $layout = panels_get_layout($display->layout); + $form_state['layout'] = $layout; + + ctools_include('dependent'); + + if ($form_state['display_title']) { + $form['display_title'] = array ( + '#tree' => TRUE, + ); + + $form['display_title']['hide_title'] = array( + '#type' => 'select', + '#title' => t('Title type'), + '#default_value' => (int) $display->hide_title, + '#options' => array( + PANELS_TITLE_NONE => t('No title'), + PANELS_TITLE_FIXED => t('Manually set'), + PANELS_TITLE_PANE => t('From pane'), + ), + ); + + $form['display_title']['title'] = array( + '#type' => 'textfield', + '#default_value' => $display->title, + '#title' => t('Title'), + '#description' => t('The title of this panel. If left blank, a default title may be used. Set to No Title if you want the title to actually be blank.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-display-title-hide-title' => array(PANELS_TITLE_FIXED)), + ); + + if (!empty($display->context)) { + $form['display_title']['title']['#description'] .= ' ' . t('You may use substitutions in this title.'); + + // We have to create a manual fieldset because fieldsets do not support IDs. + // Use 'hidden' instead of 'markup' so that the process will run. + // Add js for collapsible fieldsets manually + drupal_add_js('misc/collapse.js'); + $form['display_title']['contexts_prefix'] = array( + '#type' => 'hidden', + '#id' => 'edit-display-substitutions', + '#prefix' => '<div><fieldset id="edit-display-substitutions" class="collapsed collapsible"><legend>' . t('Substitutions') . '</legend>', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-display-title-hide-title' => array(PANELS_TITLE_FIXED)), + ); + + $rows = array(); + foreach ($display->context as $context) { + foreach (ctools_context_get_converters('%' . check_plain($context->keyword) . ':', $context) as $keyword => $title) { + $rows[] = array( + check_plain($keyword), + t('@identifier: @title', array('@title' => $title, '@identifier' => $context->identifier)), + ); + } + } + + $header = array(t('Keyword'), t('Value')); + $form['display_title']['contexts'] = array( + '#value' => theme('table', $header, $rows), + ); + $form['display_title']['contexts_suffix'] = array( + '#value' => '</fieldset></div>', + ); + } + } + + // TODO doc the ability to do this as part of the API + if (!empty($layout['settings form']) && function_exists($layout['settings form'])) { + $form['layout_settings'] = $layout['settings form']($display, $layout, $display->layout_settings); + } + $form['layout_settings']['#tree'] = TRUE; + + return $form; +} + +/** + * Validate the layout settings form. + */ +function panels_edit_display_settings_form_validate($form, &$form_state) { + if ($function = panels_plugin_get_function('layout', $form_state['layout'], 'settings validate')) { + $function($form_state['values']['layout_settings'], $form['layout_settings'], $form_state['display'], $form_state['layout'], $form_state['display']->layout_settings); + } +} + +/** + * Store changes from the layout settings form. + */ +function panels_edit_display_settings_form_submit($form, &$form_state) { + $display = &$form_state['display']; + if ($function = panels_plugin_get_function('layout', $form_state['layout'], 'settings submit')) { + $function($form_state['values']['layout_settings'], $display, $form_state['layout'], $display->layout_settings); + } + + // Since not all layouts have layout settings, check here in case of notices. + if (isset($form_state['values']['layout_settings'])) { + $display->layout_settings = $form_state['values']['layout_settings']; + } + + if (isset($form_state['values']['display_title']['title'])) { + $display->title = $form_state['values']['display_title']['title']; + $display->hide_title = $form_state['values']['display_title']['hide_title']; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/display-layout.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/display-layout.inc new file mode 100644 index 0000000000000000000000000000000000000000..da3acce83f9dbef28dbed7f7de98eb5dab2886f6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/display-layout.inc @@ -0,0 +1,294 @@ +<?php + +/** + * @file + * + * Handle the forms for changing a display's layout. + */ + +/** + * Handle calling and processing of the form for editing display layouts. + * + * Helper function for panels_edit_layout(). + * + * @see panels_edit_layout() for details on the various behaviors of this function. + */ +function _panels_edit_layout($display, $finish, $destination, $allowed_layouts) { + ctools_include('common', 'panels'); + ctools_include('form'); + + $form_state = array( + 'display' => &$display, + 'finish' => $finish, + 'destination' => $destination, + 'allowed_layouts' => $allowed_layouts, + 're_render' => FALSE, + 'no_redirect' => TRUE, + ); + + $change_form_state = $form_state; + + $change_form = FALSE; + + // Examine $_POST to see which form they're currently using. + if (empty($_POST) || empty($_POST['form_id']) || $_POST['form_id'] != 'panels_change_layout') { + $output = ctools_build_form('panels_choose_layout', $form_state); + if (empty($output)) { + // upon submission go to next form. + $change_form_state['layout'] = $_SESSION['layout'][$display->did] = $form_state['layout']; + $change_form = TRUE; + } + } + else { + $change_form_state['layout'] = $_SESSION['layout'][$display->did]; + $change_form = TRUE; + } + + if ($change_form) { + $output = ctools_build_form('panels_change_layout', $change_form_state); + if (empty($output)) { + if (isset($change_form_state['back'])) { + $_POST = array(); + return _panels_edit_layout($display, $finish, $destination, $allowed_layouts); + } + + if (!empty($change_form_state['clicked_button']['#save-display'])) { + drupal_set_message(t('Panel layout has been updated.')); + panels_save_display($display); + } + + if ($destination) { + return panels_goto($destination); + } + return $change_form_state['display']; + } + } + return $output; +} + +/** + * Form definition for the display layout editor. + * + * @ingroup forms + */ +function panels_choose_layout(&$form_state) { + $display = &$form_state['display']; + ctools_include('common', 'panels'); + ctools_include('cleanstring'); + + $layouts = panels_common_get_allowed_layouts($form_state['allowed_layouts']); + $categories = array(); + $current = ''; + foreach ($layouts as $id => $layout) { + $category = ctools_cleanstring($layout['category']); + // Default category to first in case layout doesn't exist or there isn't one. + if (empty($current)) { + $current = $category; + } + + $categories[$category] = $layout['category']; + $options[$category][$id] = panels_print_layout_icon($id, $layout, check_plain($layout['title'])); + + // Set current category to what is chosen. + if ($id == $display->layout) { + $current = $category; + } + } + + ctools_add_js('layout', 'panels'); + + $form['categories'] = array( + '#title' => t('Category'), + '#type' => 'select', + '#options' => $categories, + '#default_value' => $current, + ); + + $form['layout'] = array( + '#prefix' => '<div class="panels-choose-layout panels-layouts-checkboxes clear-block">', + '#suffix' => '</div>', + ); + + // We set up the dependencies manually because these aren't really form + // items. It's possible there's a simpler way to do this, but I could not + // think of one at the time. + $dependencies = array(); + foreach ($options as $category => $radios) { + $dependencies['panels-layout-category-' . $category] = array( + 'values' => array('edit-categories' => array($category)), + 'num' => 1, + 'type' => 'hide', + ); + + $form['layout'][$category] = array( + '#prefix' => '<div id="panels-layout-category-' . $category . '-wrapper"><div id="panels-layout-category-' . $category . '" class="form-checkboxes clear-block"><div class="panels-layouts-category">' . $categories[$category] . '</div>', + '#suffix' => '</div></div>', + ); + + foreach ($radios as $key => $choice) { + // Generate the parents as the autogenerator does, so we will have a + // unique id for each radio button. + $form['layout'][$category][$key] = array( + '#type' => 'radio', + '#title' => $choice, + '#parents' => array('layout'), + '#id' => form_clean_id('edit-layout-' . $key), + '#return_value' => check_plain($key), + '#default_value' => in_array($display->layout, array_keys($layouts)) ? $display->layout : NULL, + ); + } + } + + ctools_add_js('dependent'); + $js['CTools']['dependent'] = $dependencies; + drupal_add_js($js, 'setting'); + + + if (empty($form_state['no buttons'])) { + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Next'), + ); + } + + return $form; +} + +/** + * Handle form submission of the display layout editor. + */ +function panels_choose_layout_submit($form, &$form_state) { + $form_state['layout'] = $form_state['values']['layout']; +} + +/** + * Form definition for the display layout converter. + * + * This form is only triggered if the user attempts to change the layout + * for a display that has already had content assigned to it. It allows + * the user to select where the panes located in to-be-deleted panels should + * be relocated to. + * + * @ingroup forms + * + * @param array $form + * A structured FAPI $form array. + * @param object $display instanceof panels_display \n + * The panels_display object that was modified on the preceding display layout + * editing form. + * @param string $new_layout_id + * A string containing the name of the layout the display is to be converted to. + * These strings correspond exactly to the filenames of the *.inc files in panels/layouts. + * So, if the new layout that's been selected is the 'Two Column bricks' layout, then + * $new_layout_id will be 'twocol_bricks', corresponding to panels/layouts/twocol_bricks.inc. + */ +function panels_change_layout(&$form_state) { + $display = &$form_state['display']; + + $new_layout = panels_get_layout($form_state['layout']); + $new_layout_panels = panels_get_regions($new_layout, $display); + + $options = $new_layout_panels; + $keys = array_keys($options); + $default = current($options); + + $old_layout = panels_get_layout($display->layout); + + $form['container'] = array( + '#prefix' => '<div class="change-layout-display">', + '#suffix' => '</div>', + ); + + $form['container']['old_layout'] = array( + '#value' => panels_print_layout_icon($display->layout, $old_layout, check_plain($old_layout['title'])), + ); + + $form['container']['right_arrow'] = array( + '#value' => theme('image', drupal_get_path('module', 'panels') . '/images/go-right.png'), + ); + $form['container']['new_layout'] = array( + '#value' => panels_print_layout_icon($form_state['layout'], $new_layout, check_plain($new_layout['title'])), + ); + + $form['container-clearer'] = array( + // TODO: FIx this ot use clear-block instead + '#value' => '<div style="clear: both;"></div>', + ); + + $form['old'] = array( + '#tree' => true, + '#prefix' => '<div class="panels-layout-list">', + '#suffix' => '</div>', + ); + + $old_layout_panels = panels_get_regions($old_layout, $display); + if (empty($display->panels)) { + $form['old'] = array( + '#prefix' => '<div>', + '#value' => t('There is no content in the panel display. If there were content, you would be given an opportunity to select where in the new layout the old content would be placed. Select "Save" or "Continue" to proceed. This change will not be processed if you do not continue.'), + '#suffix' => '</div>', + ); + } + + foreach ($display->panels as $id => $content) { + $form['old'][$id] = array( + '#type' => 'select', + '#title' => t('Move content in @layout to', array('@layout' => $old_layout_panels[$id])), + '#options' => $options, + '#default_value' => array_key_exists($id, $options) ? $id : $default, + ); + } + + if (empty($form_state['no buttons'])) { + $form['back'] = array( + '#type' => 'submit', + '#value' => t('Back'), + '#submit' => array('panels_choose_layout_back'), + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => $form_state['finish'], + '#submit' => array('panels_change_layout_submit'), + '#save-display' => TRUE, + ); + } + return $form; +} + +/** + * Handle submission of the change layout form. + * + * This submit handler will move panes around and save the display. + */ +function panels_change_layout_submit($form, &$form_state) { + $display = &$form_state['display']; + + if (!empty($form_state['values']['old'])) { + foreach ($form_state['values']['old'] as $id => $new_id) { + if (isset($display->panels[$id])) { + if (!isset($content[$new_id])) { + $content[$new_id] = array(); + } + $content[$new_id] = array_merge($content[$new_id], $display->panels[$id]); + } + foreach ($content[$new_id] as $pid) { + $display->content[$pid]->panel = $new_id; + } + } + + $display->panels = $content; + } + + $display->layout = $form_state['layout']; +} + +/** + * Handle submission of the change layout form. + * + * This submit handler sets a flag on the form state, which is then used + * by the calling wrapper to restart the process. + */ +function panels_choose_layout_back($form, &$form_state) { + $form_state['back'] = TRUE; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/display-render.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/display-render.inc new file mode 100644 index 0000000000000000000000000000000000000000..8f0433f4d0b430a385904fd1b089f0e5916e19b9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/display-render.inc @@ -0,0 +1,104 @@ +<?php + +/** + * @file + * + * Contains Panels display rendering functions. + */ + +/** + * Render the administrative layout of a display. + * + * This is used for the edit version, so that layouts can have different + * modes, such as the flexible layout designer mode. + */ +function panels_render_layout_admin($layout, $content, $display) { + // @todo This should be abstracted. + if (!empty($layout['css'])) { + if (file_exists(path_to_theme() . '/' . $layout['css'])) { + drupal_add_css(path_to_theme() . '/' . $layout['css']); + } + else { + drupal_add_css($layout['path'] . '/' . $layout['css']); + } + } + + if (isset($layout['admin css'])) { + drupal_add_css($layout['path'] . '/' . $layout['admin css']); + } + + $theme = isset($layout['admin theme']) ? $layout['admin theme'] : $layout['theme']; + return theme($theme, isset($display->css_id) ? $display->css_id : '', $content, $display->layout_settings, $display, $layout); +} + +/** + * Render a pane using the appropriate style. + * + * Legacy function; this behavior has been moved onto the display renderer + * object. The function name here is included for backwards compatibility. New + * style plugins should NEVER call it. + * + * $content + * The already rendered content via panels_render_pane_content() + * $pane + * The $pane information from the display + * $display + * The display. + */ +function panels_render_pane($content, $pane, &$display) { + if ($display->hide_title == PANELS_TITLE_PANE && !empty($display->title_pane) && $display->title_pane == $pane->pid) { + + // If the user selected to override the title with nothing, and selected + // this as the title pane, assume the user actually wanted the original + // title to bubble up to the top but not actually be used on the pane. + if (empty($content->title) && !empty($content->original_title)) { + $display->stored_pane_title = $content->original_title; + } + else { + $display->stored_pane_title = !empty($content->title) ? $content->title : ''; + } + } + + if (!empty($content->content)) { + if (!empty($pane->style['style'])) { + $style = panels_get_style($pane->style['style']); + + if (isset($style) && isset($style['render pane'])) { + $output = theme($style['render pane'], $content, $pane, $display, $style); + + // This could be null if no theme function existed. + if (isset($output)) { + return $output; + } + } + } + + // fallback + return theme('panels_pane', $content, $pane, $display); + } +} + +/** + * Given a display and the id of a panel, get the style in which to render + * that panel. + */ +function panels_get_panel_style_and_settings($panel_settings, $panel) { + if (empty($panel_settings)) { + return array(panels_get_style('default'), array()); + } + + if (empty($panel_settings[$panel]['style']) || $panel_settings[$panel]['style'] == -1) { + if (empty($panel_settings['style'])) { + return array(panels_get_style('default'), array()); + } + + $style = panels_get_style($panel_settings['style']); + $style_settings = isset($panel_settings['style_settings']['default']) ? $panel_settings['style_settings']['default'] : array(); + } + else { + $style = panels_get_style($panel_settings[$panel]['style']); + $style_settings = isset($panel_settings['style_settings'][$panel]) ? $panel_settings['style_settings'][$panel] : array(); + } + + return array($style, $style_settings); +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/legacy.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/legacy.inc new file mode 100644 index 0000000000000000000000000000000000000000..46e13c32577446d8f7c342c5e220821f87fb48df --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/legacy.inc @@ -0,0 +1,70 @@ +<?php + +/** + * Legacy state manager for Panels. + * + * Checks all possible ways (using discovery of patterned method names) in which + * Panels may need to operate in legacy mode, + * sets variables as appropriate, and returns an informational + * + */ +class PanelsLegacyState { + var $legacy = NULL; + + function t() { + $func = get_t(); + $args = func_get_args(); + return call_user_func_array($func, $args); + } + + function getStatus() { + if (!isset($this->legacy)) { + $this->determineStatus(); + } + return $this->legacy; + } + + /** + * Run all compatibility checks. + */ + function determineStatus() { + $this->legacy = array(); + foreach(get_class_methods($this) as $method) { + if (strtolower(substr($method, 0, 5)) == 'check') { + $this->legacy[$method] = $this->$method(); + } + } + $this->legacy = array_filter($this->legacy); + } + + /** + * Compatibility checker that ensures modules that implement Panels styles + * list their api as being at least 2.0; this corresponds to the change with + * the initial IPE commit that made region styles take a fully rendered pane + * HTML string instead of a pane object that still needed rendering. + */ + function checkStylesIPE1() { + $legacy_info = array( + 'explanation' => $this->t('Panels 3.6 made changes to the rendering order in a way that affects certain style plugins. The above modules implement style plugins, but have not indicated their compatibility with this new system. See !link for information on how to update style plugins to the new system.', array('!link' => url('http://drupal.org/node/865840', array('external' => TRUE)))), + 'modules' => array(), + ); + + + $naughties = &$legacy_info['modules']; + $legacy = FALSE; + + ctools_include('plugins', 'panels'); + // TODO given that the plugin cache is also clearing at this time, should + // check this to ensure this isn't causing some kind of weird race condition + $styles = panels_get_styles(); + + foreach ($styles as $style) { + if (version_compare($style['version'], 2.0, '<') && empty($naughties[$style['module']])) { + $legacy = TRUE; + $naughties[$style['module']] = $this->t('Style plugins'); + } + } + variable_set('panels_legacy_rendering_mode', $legacy); + return $legacy ? $legacy_info : array(); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/page-wizard.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/page-wizard.inc new file mode 100644 index 0000000000000000000000000000000000000000..b649ff3cb4264691a06a163e0c23fcc3049715d7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/page-wizard.inc @@ -0,0 +1,67 @@ +<?php + +/** + * @file + * Contains helper functions for the Panels page wizards. + */ +function panels_page_wizard_add_layout(&$form, &$form_state) { + $form_state['allowed_layouts'] = 'panels_page'; + $form_state['display'] = $form_state['cache']->display; + + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + + // Change the #id of the form so the CSS applies properly. + $form['#id'] = 'panels-choose-layout'; + + $form['layout_prefix'] = array( + '#value' => '<fieldset><legend>' . t('Layout') . '</legend>', + ); + + ctools_include('common', 'panels'); + ctools_include('display-layout', 'panels'); + ctools_include('plugins', 'panels'); + + $form = array_merge($form, panels_choose_layout($form_state)); + + $form['layout_suffix'] = array( + '#value' => '</fieldset>', + ); +} + +function panels_page_wizard_add_content(&$form, &$form_state) { + ctools_include('ajax'); + ctools_include('plugins', 'panels'); + ctools_include('common', 'panels'); + ctools_include('display-edit', 'panels'); + + // Panels provides this caching mechanism to make it easy to use the + // wizard to cache the display. + + $cache = panels_edit_cache_get('panels_page_wizard:node_override'); + + $form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display); + $form_state['renderer']->cache = &$cache; + + $form_state['display'] = &$cache->display; + $form_state['content_types'] = $cache->content_types; + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + $form_state['display_title'] = !empty($cache->display_title); + + $form = array_merge($form, panels_edit_display_form($form_state)); + // Make sure the theme will work since our form id is different. + $form['#theme'] = 'panels_edit_display_form'; +} + +function panels_page_wizard_add_content_submit(&$form, &$form_state) { + // Call the normal panels edit form submit to make sure values are stored + // on the display + panels_edit_display_form_submit($form, $form_state); + $cache = &$form_state['cache']; + + // Copy the "being edited" cached display to the "actual" cached display. + $cache->display = &$form_state['display']; + unset($cache->display_cache); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/panels.pipelines.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/panels.pipelines.inc new file mode 100644 index 0000000000000000000000000000000000000000..c41a2872c0b44a48adf8a679792368505affaed8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/panels.pipelines.inc @@ -0,0 +1,33 @@ +<?php + +/** + * @file + * Bulk export of panels_layouts objects generated by Bulk export module. + */ + +/** + * Implementation of hook_default_panels_renderer_pipeline(). + */ +function panels_default_panels_renderer_pipeline() { + $pipelines = array(); + + $pipeline = new stdClass; + $pipeline->disabled = FALSE; /* Edit this to true to make a default pipeline disabled initially */ + $pipeline->api_version = 1; + $pipeline->name = 'standard'; + $pipeline->admin_title = t('Standard'); + $pipeline->admin_description = t('Renders a panel normally. This is the most common option.'); + $pipeline->weight = -100; + $pipeline->settings = array( + 'renderers' => array( + 0 => array( + 'access' => array(), + 'renderer' => 'standard', + 'options' => array(), + ), + ), + ); + $pipelines[$pipeline->name] = $pipeline; + + return $pipelines; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/includes/plugins.inc b/drupal/sites/default/boinc/modules/contrib/panels/includes/plugins.inc new file mode 100644 index 0000000000000000000000000000000000000000..00a3847ddf306b58ff7460dd2fc794b897be5964 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/includes/plugins.inc @@ -0,0 +1,509 @@ +<?php + +/** + * @file + * + * Contains helper code for plugins and contexts. + */ + +/** + * Determine if a pane is visible. + * + * @param $pane + * The pane object to test for access. + * @param $display + * The display object containing the pane object to be tested. + */ +function panels_pane_access($pane, $display) { + ctools_include('context'); + return ctools_access($pane->access, $display->context); +} + +/** + * Get a list of panels available in the layout. + */ +function panels_get_regions($layout, $display) { + if (!empty($layout['panels function']) && function_exists($layout['panels function'])) { + return $layout['panels function']($display, $display->layout_settings, $layout); + } + if (!empty($layout['panels'])) { + return $layout['panels']; + } + return array(); +} + +/** + * Get cached content for a given display and possibly pane. + * + * @return + * The cached content, or FALSE to indicate no cached content exists. + */ +function panels_get_cached_content($display, $args, $context, $pane = NULL) { + // Never use cache on a POST + if (!empty($_POST)) { + return FALSE; + } + + $method = $pane ? $pane->cache['method'] : $display->cache['method']; + $function = panels_plugin_get_function('cache', $method, 'cache get'); + + if (!$function) { + return FALSE; + } + + $conf = $pane ? $pane->cache['settings'] : $display->cache['settings']; + $cache = $function($conf, $display, $args, $context, $pane); + if (empty($cache)) { + return FALSE; + } + + // restore it. + $cache->restore(); + return $cache; +} + +/** + * Store cached content for a given display and possibly pane. + */ +function panels_set_cached_content($cache, $display, $args, $context, $pane = NULL) { + // Never use cache on a POST + if (!empty($_POST)) { + return FALSE; + } + + $method = $pane ? $pane->cache['method'] : $display->cache['method']; + $function = panels_plugin_get_function('cache', $method, 'cache set'); + + if (!$function) { + return FALSE; + } + + $conf = $pane ? $pane->cache['settings'] : $display->cache['settings']; + + // snapshot it. + $cache->cache(); + return $function($conf, $cache, $display, $args, $context, $pane); +} + +/** + * Clear all cached content for a display. + */ +function panels_clear_cached_content($display) { + // Figure out every method we might be using to cache content in this display: + $methods = array(); + if (!empty($display->cache['method'])) { + $methods[$display->cache['method']] = TRUE; + } + + foreach ($display->content as $pane) { + if (!empty($pane->cache['method'])) { + $methods[$pane->cache['method']] = TRUE; + } + } + + foreach (array_keys($methods) as $method) { + $function = panels_plugin_get_function('cache', $method, 'cache clear'); + if ($function) { + $function($display); + } + } +} + +/** + * An object to hold caching information while it is happening. + */ +class panels_cache_object { + var $content = ''; + var $head = NULL; + var $css = NULL; + var $js = NULL; + var $tokens = NULL; + var $ready = FALSE; + + /** + * When constructed, take a snapshot of our existing out of band data. + */ + function panels_cache_object() { + $this->head = drupal_set_html_head(); + $this->css = drupal_add_css(); + $this->tokens = ctools_set_page_token(); + + foreach (array('header', 'footer') as $scope) { + $this->js[$scope] = drupal_add_js(NULL, NULL, $scope); + } + } + + /** + * Add content to the cache. This assumes a pure stream; + * use set_content() if it's something else. + */ + function add_content($content) { + $this->content .= $content; + } + + function set_content($content) { + $this->content = $content; + } + + /** + * Set the object for storing. This overwrites. + */ + function cache() { + if ($this->ready) { + return; + } + + $this->ready = TRUE; + + // Simple replacement for head + $this->head = str_replace($this->head, '', drupal_set_html_head()); + + // Slightly less simple for CSS: + $css = drupal_add_css(); + $start = $this->css; + $this->css = array(); + + foreach ($css as $media => $medias) { + foreach ($medias as $type => $types) { + foreach ($types as $path => $preprocess) { + if (!isset($start[$media][$type][$path])) { + $this->css[] = array($path, $type, $media, $preprocess); + } + } + } + } + + $js = array(); + // A little less simple for js + foreach (array('header', 'footer') as $scope) { + $js[$scope] = drupal_add_js(NULL, NULL, $scope); + } + + $start = $this->js; + $this->js = array(); + + foreach ($js as $scope => $scopes) { + foreach ($scopes as $type => $types) { + foreach ($types as $id => $info) { + if (!isset($start[$scope][$type][$id])) { + switch ($type) { + case 'setting': + $this->js[] = array($info, $type, $scope); + break; + + case 'inline': + $this->js[] = array($info['code'], $type, $scope, $info['defer']); + break; + + default: + $this->js[] = array($id, $type, $scope, $info['defer'], $info['cache']); + } + } + } + } + } + + // And for tokens: + $tokens = ctools_set_page_token(); + foreach ($this->tokens as $token => $argument) { + if (isset($tokens[$token])) { + unset($tokens); + } + } + + $this->tokens = $tokens; + } + + /** + * Restore out of band data saved to cache. + */ + function restore() { + if (!empty($this->head)) { + drupal_set_html_head($this->head); + } + if (!empty($this->css)) { + foreach ($this->css as $args) { + call_user_func_array('drupal_add_css', $args); + } + } + if (!empty($this->js)) { + foreach ($this->js as $args) { + call_user_func_array('drupal_add_js', $args); + } + } + + if (!empty($this->tokens)) { + foreach ($this->tokens as $token => $key) { + list($type, $argument) = $key; + ctools_set_page_token($token, $type, $argument); + } + } + } +} + +/** + * Get the title of a pane. + * + * @param $pane + * The $pane object. + */ +function panels_get_pane_title(&$pane, $context = array(), $incoming_content = NULL) { + ctools_include('content'); + return ctools_content_admin_title($pane->type, $pane->subtype, $pane->configuration, $context); +} + +/** + * Fetch metadata on a specific layout plugin. + * + * @param $layout + * Name of a panel layout. If the layout name contains a ':' this + * indicates that we need to separate the sublayout out and + * load it individually. + * + * @return + * An array with information about the requested panel layout. + */ +function panels_get_layout($layout) { + ctools_include('plugins'); + return ctools_get_plugins('panels', 'layouts', $layout); +} + +/** + * Fetch metadata for all layout plugins. + * + * @return + * An array of arrays with information about all available panel layouts. + */ +function panels_get_layouts() { + ctools_include('plugins'); + return ctools_get_plugins('panels', 'layouts'); +} + +/** + * Fetch metadata for all layout plugins that provide builders. + * + * The layout builders allow reusable layouts be stored in the database and + * exported. Since there are different methods, we are not limiting this + * to just one plugin. + * + * @return + * An array of arrays with information about panel layouts with builders. + */ +function panels_get_layout_builders() { + ctools_include('plugins'); + $plugins = ctools_get_plugins('panels', 'layouts'); + $builders = array(); + foreach ($plugins as $name => $plugin) { + if (!empty($plugin['builder'])) { + $builders[$name] = $plugin; + } + } + + return $builders; +} + +/** + * Fetch metadata on a specific style plugin. + * + * @param $style + * Name of a panel style. + * + * @return + * An array with information about the requested panel style. + */ +function panels_get_style($style) { + ctools_include('plugins'); + return ctools_get_plugins('panels', 'styles', $style); +} + +/** + * Fetch metadata for all style plugins. + * + * @return + * An array of arrays with information about all available panel styles. + */ +function panels_get_styles() { + ctools_include('plugins'); + return ctools_get_plugins('panels', 'styles'); +} + +/** + * Fetch metadata on a specific caching plugin. + * + * @param $cache + * Name of a panel cache. + * + * @return + * An array with information about the requested panel cache. + */ +function panels_get_cache($cache) { + ctools_include('plugins'); + return ctools_get_plugins('panels', 'cache', $cache); +} + +/** + * Fetch metadata for all context plugins. + * + * @return + * An array of arrays with information about all available panel caches. + */ +function panels_get_caches() { + ctools_include('plugins'); + return ctools_get_plugins('panels', 'cache'); +} + +/** + * Fetch metadata on a specific display renderer plugin. + * + * @return + * An array of arrays with information about the requested panels display + * renderer. + */ +function panels_get_display_renderer($renderer) { + ctools_include('plugins'); + return ctools_get_plugins('panels', 'display_renderers', $renderer); +} + +/** + * Fetch metadata for all display renderer plugins. + * + * @return + * An array of arrays with information about all available panels display + * renderer. + */ +function panels_get_display_renderers() { + ctools_include('plugins'); + return ctools_get_plugins('panels', 'display_renderers'); +} + +/** + * Get and initialize the class to handle rendering a display. + * + * @return + * Either the instantiated renderer or FALSE if one could not be found. + */ +function panels_get_renderer_handler($plugin, &$display) { + if (is_string($plugin)) { + $plugin = panels_get_display_renderer($plugin); + } + + $class = ctools_plugin_get_class($plugin, 'handler'); + if ($class) { + $renderer = new $class(); + $renderer->init($plugin, $display); + return $renderer; + } + + return FALSE; +} + +/** + * Choose a renderer for a display based on a render pipeline setting. + */ +function panels_get_renderer($pipeline_name, &$display) { + // If operating in legacy mode, only the legacy renderer is available: + if (variable_get('panels_legacy_rendering_mode', TRUE)) { + return panels_get_renderer_handler('legacy', $display); + } + + // Load the pipeline + ctools_include('export'); + $pipeline = ctools_export_crud_load('panels_renderer_pipeline', $pipeline_name); + + // If we can't, or it has no renderers, default. + if (!$pipeline || empty($pipeline->settings['renderers'])) { + return panels_get_renderer_handler('standard', $display); + } + + // Get contexts set on the pipeline: + $contexts = array(); + if (!empty($pipeline->settings['contexts'])) { + $contexts = ctools_context_load_contexts($pipeline->settings['context']); + } + + // Cycle through our renderers and see. + foreach ($pipeline->settings['renderers'] as $candidate) { + // See if this passes selection criteria. + if (!ctools_access($candidate['access'], $contexts)) { + continue; + } + + $renderer = panels_get_renderer_handler($candidate['renderer'], $display); + + if (!empty($candidate['options'])) { + $renderer->set_options($candidate['options']); + } + + return $renderer; + } + + // Fall through. If no renderer is selected, use the standard renderer + return panels_get_renderer_handler('standard', $display); +} + +/** + * Sort callback for sorting renderer pipelines. + * + * Sort first by weight, then by title. + */ +function _panels_renderer_pipeline_sort($a, $b) { + if ($a->weight == $b->weight) { + if ($a->admin_title == $b->admin_title) { + return 0; + } + return ($a->admin_title < $b->admin_title) ? -1 : 1; + } + return ($a->weight < $b->weight) ? -1 : 1; +} + +/** + * Get a list of available renderer pipelines. + * + * This can be used to form a select or radios widget by enabling + * sorting. Descriptions are left in. + */ +function panels_get_renderer_pipelines($sort = TRUE) { + // If operating in legacy mode, only the legacy renderer is available: + if (variable_get('panels_legacy_rendering_mode', TRUE)) { + return array(); + } + + ctools_include('export'); + $pipelines = ctools_export_crud_load_all('panels_renderer_pipeline'); + if ($sort) { + uasort($pipelines, '_panels_renderer_pipeline_sort'); + } + + return $pipelines; +} + +/** + * Get a function from a plugin, if it exists. + * + * @param $plugin + * The type of plugin + * @param $which + * Either the loaded plugin object (or the same data in array form) + * or a string with the name of the desired the specific plugin. + * @param $function_name + * The identifier of the function. For example, 'settings form'. + * + * @return + * The actual name of the function to call, or NULL if the function + * does not exist. + */ +function panels_plugin_get_function($plugin, $which, $function_name) { + ctools_include('plugins'); + if (is_object($which) || is_array($which)) { + return ctools_plugin_get_function($which, $function_name); + } + else { + return ctools_plugin_load_function('panels', $plugin, $which, $function_name); + } + +} + +// @todo these are DEPRECATED and can probably be removed. +// These are placeholders to prevent crashes from the former plugins +class panels_required_context { function filter() { } }; +class panels_optional_context extends panels_required_context {}; diff --git a/drupal/sites/default/boinc/modules/contrib/panels/js/display_editor.js b/drupal/sites/default/boinc/modules/contrib/panels/js/display_editor.js new file mode 100644 index 0000000000000000000000000000000000000000..dff640704d757e9cacff3245bde56ebbf7eaf8f5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/js/display_editor.js @@ -0,0 +1,513 @@ +/** + * @file display_editor.js + * + * Contains the javascript for the Panels display editor. + */ + +(function ($) { + /** Delete pane button **/ + Drupal.Panels.bindClickDelete = function(context) { + $('a.pane-delete:not(.pane-delete-processed)', context) + .addClass('pane-delete-processed') + .click(function() { + if (confirm('Remove this pane?')) { + var id = '#' + $(this).attr('id').replace('pane-delete-', ''); + $(id).remove(); + Drupal.Panels.Draggable.savePositions(); + } + return false; + }); + }; + + Drupal.Panels.bindPortlet = function() { + var handle = $(this).find('.panel-pane-collapsible > div.pane-title'); + var content = $(this).find('.panel-pane-collapsible > div.pane-content'); + if (content.length) { + var toggle = $('<span class="toggle toggle-collapsed"></span>'); + handle.before(toggle); + toggle.click(function() { + content.slideToggle(20); + toggle.toggleClass('toggle-collapsed'); + }); + handle.click(function() { + content.slideToggle(20); + toggle.toggleClass('toggle-collapsed'); + }); + content.hide(); + } + }; + + Drupal.Panels.Draggable = { + // The draggable object + object: null, + + // Where objects can be dropped + dropzones: [], + current_dropzone: null, + + // positions within dropzones where an object can be plazed + landing_pads: [], + current_pad: null, + + // Where the object is + mouseOffset: { x: 0, y: 0 }, + windowOffset: { x: 0, y: 0 }, + offsetDivHeight: 0, + + // original settings to be restored + original: {}, + // a placeholder so that if the object is let go but not over a drop zone, + // it can be put back where it belongs + placeholder: {}, + + hoverclass: 'hoverclass', + helperclass: 'helperclass', + accept: 'div.panels-display', + handle: 'div.grabber', + draggable: 'div.panel-portlet', + main: 'div#panels-dnd-main', + + // part of the id to remove to get just the number + draggableId: 'panel-pane-', + // What to add to the front of a the id to get the form id for a panel + formId: 'input#edit-', + + maxWidth: 250, + + unsetDropZone: function() { + $(this.current_dropzone.obj).removeClass(this.hoverclass); + this.current_dropzone = null; + for (var i in this.landing_pads) { + $(this.landing_pads[i].obj).remove(); + } + this.landing_pads = []; + this.current_pad = null; + }, + + createLandingPad: function(where, append) { + var obj = $('<div class="' + this.helperclass +'" id="' + + $(where).attr('id') + '-dropzone"> </div>'); + if (append) { + $(where).append(obj); + } + else { + $(where).before(obj); + } + var offset = $(obj).offset(); + + $(obj).css({ + display: 'none' + }); + this.landing_pads.push({ + centerX: offset.left + ($(obj).innerWidth() / 2), + centerY: offset.top + ($(obj).innerHeight() / 2), + obj: obj + }); + return obj; + }, + + calculateDropZones: function(event, dropzone) { + var dropzones = []; + $(this.accept).each(function() { + var offset = $(this).offset({padding:true}); + offset.obj = this; + offset.width = $(this).outerWidth(); + offset.height = $(this).outerHeight(); + dropzones.push(offset); + }); + this.dropzones = dropzones; + }, + + reCalculateDropZones: function() { + for (var i in this.dropzones) { + offset = $(this.dropzones[i].obj).offset({padding:true}); + offset.width = $(this.dropzones[i].obj).outerWidth(); + offset.height = $(this.dropzones[i].obj).outerHeight(); + $.extend(this.dropzones[i], offset); + } + }, + + changeDropZone: function(new_dropzone) { + // Unset our old dropzone. + if (this.current_dropzone) { + this.unsetDropZone(); + } + + // Set up our new dropzone. + this.current_dropzone = new_dropzone; + $(this.current_dropzone.obj).addClass(this.hoverclass); + // add a landing pad + this.createLandingPad(this.current_dropzone.obj, true); + + var that = this; + // Create a landing pad before each existing portlet. + $(this.current_dropzone.obj).find(this.draggable).each(function() { + if (that.object.id != this.id) { + that.createLandingPad(this, false); + } + }); + }, + + findLandingPad: function(x, y) { + var shortest_distance = null; + var nearest_pad = null; + // find the nearest pad. + for (var i in this.landing_pads) { + // This isn't the real distance, this is the square of the + // distance -- no point in spending processing time on + // sqrt. + var dstx = Math.abs(x - this.landing_pads[i].centerX); + var dsty = Math.abs(y - this.landing_pads[i].centerY); + var distance = (dstx * dstx) + (dsty * dsty); + if (shortest_distance == null || distance < shortest_distance) { + shortest_distance = distance; + nearest_pad = this.landing_pads[i]; + } + } + if (nearest_pad != this.current_pad) { + if (this.current_pad) { + $(this.current_pad.obj).hide(); + } + this.current_pad = nearest_pad; + $(nearest_pad.obj).show(); + } + }, + + findDropZone: function(x, y) { + // Go through our dropzones and see if we're over one. + var new_dropzone = null; + for (var i in this.dropzones) { + // console.log('x:' + x + ' left:' + this.dropzones[i].left + ' right: ' + this.dropzones[i].left + this.dropzones[i].width); + if (this.dropzones[i].left < x && + x < this.dropzones[i].left + this.dropzones[i].width && + this.dropzones[i].top < y && + y < this.dropzones[i].top + this.dropzones[i].height) { + new_dropzone = this.dropzones[i]; + break; + } + } + // If we're over one, see if it's different. + if (new_dropzone) { + var changed = false; + if (!this.current_dropzone || new_dropzone.obj.id != this.current_dropzone.obj.id) { + this.changeDropZone(new_dropzone); + changed = true; + } + this.findLandingPad(x, y); + if (changed) { + // recalculate the size of our drop zones due to the fact that we're drawing landing pads. + this.reCalculateDropZones(); + } + } + // If we're not over one, be sure to unhilite one if we were just + // over it. + else if (this.current_dropzone) { + this.unsetDropZone(); + } + }, + + /** save button clicked, or pane deleted **/ + savePositions: function() { + var draggable = Drupal.Panels.Draggable; + $(draggable.accept).each(function() { + var val = ''; + $(this).find(draggable.draggable).each(function() { + if (val) { + val += ','; + } + + val += this.id.replace(draggable.draggableId, ''); + }); + // Note: _ is replaced with - because Drupal automatically does this + // with form ids. + $(draggable.formId + this.id.replace(/_/g, '-')).val(val); + }); + return false; + } + }; + + Drupal.Panels.DraggableHandler = function() { + $(this).addClass('panel-draggable'); + var draggable = Drupal.Panels.Draggable; + var scrollBuffer = 10; + var scrollDistance = 10; + var scrollTimer = 30; + + getMouseOffset = function(docPos, mousePos, windowPos) { + return { x: mousePos.x - docPos.x + windowPos.x, y: mousePos.y - docPos.y + windowPos.y}; + }; + + getMousePos = function(ev) { + ev = ev || window.event; + + if (ev.pageX || ev.pageY) { + return { x:ev.pageX, y:ev.pageY }; + } + return { + x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, + y:ev.clientY + document.body.scrollTop - document.body.clientTop + }; + }; + + getPosition = function(e) { + /* + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(e, null); + return { + x: parseInt(css.getPropertyValue('left')), + y: parseInt(css.getPropertyValue('top')) + }; + } + */ + var left = 0; + var top = 0; + + while (e.offsetParent) { + left += e.offsetLeft; + top += e.offsetTop; + e = e.offsetParent; + } + + left += e.offsetLeft; + top += e.offsetTop; + + return { x:left, y:top }; + }; + + mouseUp = function(e) { + clearTimeout(draggable.timeoutId); + draggable.dropzones = []; + + if (draggable.current_pad) { + // Drop the object where we're hovering + $(draggable.object).insertAfter($(draggable.current_pad.obj)); + Drupal.Panels.changed($(draggable.object)); + } + else { + // or put it back where it came from + $(draggable.object).insertAfter(draggable.placeholder); + } + // remove the placeholder + draggable.placeholder.remove(); + + // restore original settings. + $(draggable.object).css(draggable.original); + if (draggable.current_dropzone) { + draggable.unsetDropZone(); + } + + $(document).unbind('mouseup').unbind('mousemove'); + draggable.savePositions(); + }; + + mouseMove = function(e) { + draggable.mousePos = getMousePos(e); + + draggable.findDropZone(draggable.mousePos.x, draggable.mousePos.y); + + var windowMoved = parseInt(draggable.offsetDivHeight - $(draggable.main).innerHeight()); + + draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + windowMoved + 'px'; + draggable.object.style.left = draggable.mousePos.x - draggable.mouseOffset.x + 'px'; + $(draggable.object).toggleClass('moving'); + }; + + mouseDown = function(e) { + // If we mouse-downed over something clickable, don't drag! + if (e.target.nodeName == 'A' || e.target.nodeName == 'INPUT' || e.target.parentNode.nodeName == 'A' || e.target.nodeName.nodeName == 'INPUT') { + return; + } + + draggable.object = $(this).parent(draggable.draggable).get(0); + + // create a placeholder so we can put this object back if dropped in an invalid location. + draggable.placeholder = $('<div class="draggable-placeholder-object" style="display:none"></div>"'); + $(draggable.object).after(draggable.placeholder); + + // Store original CSS so we can put it back. + draggable.original = { + position: $(draggable.object).css('position'), + width: 'auto', + left: $(draggable.object).css('left'), + top: $(draggable.object).css('top'), + 'z-index': $(draggable.object).css('z-index'), + 'margin-bottom': $(draggable.object).css('margin-bottom'), + 'margin-top': $(draggable.object).css('margin-top'), + 'margin-left': $(draggable.object).css('margin-left'), + 'margin-right': $(draggable.object).css('margin-right'), + 'padding-bottom': $(draggable.object).css('padding-bottom'), + 'padding-top': $(draggable.object).css('padding-top'), + 'padding-left': $(draggable.object).css('padding-left'), + 'padding-right': $(draggable.object).css('padding-right') + }; + + draggable.mousePos = getMousePos(e); + var originalPos = $(draggable.object).offset(); + var width = Math.min($(draggable.object).innerWidth(), draggable.maxWidth); + + draggable.offsetDivHeight = $(draggable.main).innerHeight(); + draggable.findDropZone(draggable.mousePos.x, draggable.mousePos.y); + + // Make copies of these because in FF3, they actually change when we + // move the item, whereas they did not in FF2. + + if (e.layerX || e.layerY) { + var layerX = e.layerX; + var layerY = e.layerY; + } + else if (e.originalEvent && e.originalEvent.layerX) { + var layerX = e.originalEvent.layerX; + var layerY = e.originalEvent.layerY; + } + + // Make the draggable relative, get it out of the way and make it + // invisible. + $(draggable.object).css({ + position: 'relative', + 'z-index': 100, + width: width + 'px', + 'margin-bottom': (-1 * parseInt($(draggable.object).outerHeight())) + 'px', + 'margin-top': 0, + 'margin-left': 0, + 'margin-right': (-1 * parseInt($(draggable.object).outerWidth())) + 'px', + 'padding-bottom': 0, + 'padding-top': 0, + 'padding-left': 0, + 'padding-right': 0, + 'left': 0, + 'top': 0 + }) + .insertAfter($(draggable.main)); + var newPos = $(draggable.object).offset(); + + var windowOffset = { left: originalPos.left - newPos.left, top: originalPos.top - newPos.top } + + // if they grabbed outside the area where we make the draggable smaller, move it + // closer to the cursor. + if (layerX != 'undefined' && layerX > width) { + windowOffset.left += layerX - 10; + } + else if (layerX != 'undefined' && e.offsetX > width) { + windowOffset.left += e.offsetX - 10; + } + + // This is stored so we can move with it. + draggable.mouseOffset = { x: draggable.mousePos.x - windowOffset.left, y: draggable.mousePos.y - windowOffset.top}; + draggable.offsetDivHeight = $(draggable.main).innerHeight(); + + draggable.object.style.top = windowOffset.top + 'px'; + draggable.object.style.left = windowOffset.left + 'px'; + $(document).unbind('mouseup').unbind('mousemove').mouseup(mouseUp).mousemove(mouseMove); + + draggable.calculateDropZones(draggable.mousePos, e); + draggable.timeoutId = setTimeout('timer()', scrollTimer); + return false; + }; + + timer = function() { + if (!draggable.timeCount) { + draggable.timeCount = 0; + } + draggable.timeCount = draggable.timeCount + 1; + var left = $(window).scrollLeft(); + var right = left + $(window).width(); + var top = $(window).scrollTop(); + var bottom = top + $(window).height(); + + if (draggable.mousePos.x < left + scrollBuffer && left > 0) { + window.scrollTo(left - scrollDistance, top); + draggable.mousePos.x -= scrollDistance; + draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + 'px'; + } + else if (draggable.mousePos.x > right - scrollBuffer) { + window.scrollTo(left + scrollDistance, top); + draggable.mousePos.x += scrollDistance; + draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + 'px'; + } + else if (draggable.mousePos.y < top + scrollBuffer && top > 0) { + window.scrollTo(left, top - scrollDistance); + draggable.mousePos.y -= scrollDistance; + draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + 'px'; + } + else if (draggable.mousePos.y > bottom - scrollBuffer) { + window.scrollTo(left, top + scrollDistance); + draggable.mousePos.y += scrollDistance; + draggable.object.style.top = draggable.mousePos.y - draggable.mouseOffset.y + 'px'; + } + + draggable.timeoutId = setTimeout('timer()', scrollTimer); + } + + $(this).mousedown(mouseDown); + }; + + $.fn.extend({ + panelsDraggable: Drupal.Panels.DraggableHandler + }); + + /** + * Implement Drupal behavior for autoattach + */ + Drupal.behaviors.PanelsDisplayEditor = function(context) { + // Show javascript only items. + $('span#panels-js-only').css('display', 'inline'); + + $('#panels-dnd-main div.panel-pane:not(.panel-portlet)') + .addClass('panel-portlet') + .each(Drupal.Panels.bindPortlet); + + // The above doesn't work if context IS the pane, so do this to catch that. + if ($(context).hasClass('panel-pane') && !$(context).hasClass('panel-portlet')) { + $(context) + .addClass('panel-portlet') + .each(Drupal.Panels.bindPortlet); + } + + // Make draggables and make sure their positions are saved. + $(context).find('div.grabber:not(.panel-draggable)').panelsDraggable(); + Drupal.Panels.Draggable.savePositions(); + + // Bind buttons. + $('input#panels-hide-all', context).click(Drupal.Panels.clickHideAll); + $('input#panels-show-all', context).click(Drupal.Panels.clickShowAll); + + Drupal.Panels.bindClickDelete(context); + + $('#panels-live-preview-button:not(.panels-preview-processed)') + .addClass('panels-preview-processed') + .click(function () { + if (!$('#panels-preview').size()) { + $('#panels-dnd-main').parents('form').after('<div id="panels-preview"></div>'); + } + + $('#panels-preview').html(Drupal.theme('CToolsModalThrobber')); + }); + + var setTitleClass = function () { + if ($('#edit-display-title-hide-title').val() == 2) { + $('#panels-dnd-main').removeClass('panels-set-title-hide'); + } + else { + $('#panels-dnd-main').addClass('panels-set-title-hide'); + } + } + + // The panes have an option to set the display title, but only if + // a select is set to the proper value. This sets a class on the + // main edit div so that the option to set the display title + // is hidden if that is not selected, and visible if it is. + $('#edit-display-title-hide-title:not(.panels-title-processed)') + .addClass('panels-title-processed') + .change(setTitleClass); + + setTitleClass(); + }; + + /** + * AJAX responder command to render the preview. + */ + Drupal.CTools.AJAX.commands.panel_preview = function(command) { + $('#panels-preview').html(command.output); + } + +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/js/layout.js b/drupal/sites/default/boinc/modules/contrib/panels/js/layout.js new file mode 100644 index 0000000000000000000000000000000000000000..e54fd022ab92b1966aeb2b6282b26552b7c75f4c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/js/layout.js @@ -0,0 +1,18 @@ +/** + * @file layout.js + * + * Contains javascript to make layout modification a little nicer. + */ + +(function ($) { + Drupal.Panels.Layout = {}; + Drupal.Panels.Layout.autoAttach = function() { + $('div.form-item div.layout-icon').click(function() { + $widget = $('input', $(this).parent()); + // Toggle if a checkbox, turn on if a radio. + $widget.attr('checked', !$widget.attr('checked') || $widget.is('input[type=radio]')); + }); + }; + + $(Drupal.Panels.Layout.autoAttach); +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/js/panels-base.js b/drupal/sites/default/boinc/modules/contrib/panels/js/panels-base.js new file mode 100644 index 0000000000000000000000000000000000000000..7b0b9223fea4a1bf6afb66cd1bcb2fc39e0751bf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/js/panels-base.js @@ -0,0 +1,28 @@ +/** + * @file + * Implement basic methods required by all of panels. + */ + +(function ($) { + Drupal.Panels = {} + + Drupal.Panels.changed = function(item) { + if (!item.is('.changed')) { + item.addClass('changed'); + item.find('div.grabber span.text').append(' <span class="star">*</span> '); + } + }; + + Drupal.Panels.restripeTable = function(table) { + // :even and :odd are reversed because jquery counts from 0 and + // we count from 1, so we're out of sync. + $('tbody tr:not(:hidden)', $(table)) + .removeClass('even') + .removeClass('odd') + .filter(':even') + .addClass('odd') + .end() + .filter(':odd') + .addClass('even'); + }; +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/js/panels.js b/drupal/sites/default/boinc/modules/contrib/panels/js/panels.js new file mode 100644 index 0000000000000000000000000000000000000000..70e8544c4e50c0bedceff951c66f930cd7aef965 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/js/panels.js @@ -0,0 +1,28 @@ + +(function ($) { + Drupal.Panels = {}; + + Drupal.Panels.autoAttach = function() { + if ($.browser.msie) { + // If IE, attach a hover event so we can see our admin links. + $("div.panel-pane").hover( + function() { + $('div.panel-hide', this).addClass("panel-hide-hover"); return true; + }, + function() { + $('div.panel-hide', this).removeClass("panel-hide-hover"); return true; + } + ); + $("div.admin-links").hover( + function() { + $(this).addClass("admin-links-hover"); return true; + }, + function(){ + $(this).removeClass("admin-links-hover"); return true; + } + ); + } + }; + + $(Drupal.Panels.autoAttach); +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels.info b/drupal/sites/default/boinc/modules/contrib/panels/panels.info new file mode 100644 index 0000000000000000000000000000000000000000..151f55303d239663ef8d075d27c2ba8d63feb87b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels.info @@ -0,0 +1,12 @@ +name = Panels +description = Core Panels display functions; provides no external UI, at least one other Panels module should be enabled. +core = 6.x +package = "Panels" +dependencies[] = ctools + +; Information added by drupal.org packaging script on 2012-01-18 +version = "6.x-3.10" +core = "6.x" +project = "panels" +datestamp = "1326917148" + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels.install b/drupal/sites/default/boinc/modules/contrib/panels/panels.install new file mode 100644 index 0000000000000000000000000000000000000000..3dcd57c8f57e9b1c7b49c6084d12e742fc2ba672 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels.install @@ -0,0 +1,1538 @@ +<?php + +/** + * Test requirements for installation and running. + */ +function panels_requirements($phase) { + $function = "panels_requirements_$phase"; + return function_exists($function) ? $function() : array(); +} + +/** + * Check install-time requirements. + */ +function panels_requirements_install() { + $requirements = array(); + $t = get_t(); + // Assume that if the user is running an installation profile that both + // Panels and CTools are the same release. + if (!(defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'install')) { + // apparently the install process doesn't include .module files, + // so we need to force the issue in order for our versioning + // check to work. + if (!defined('PANELS_REQUIRED_CTOOLS_API')) { + include_once drupal_get_path('module', 'panels') . '/panels.module'; + } + + // In theory we should check module_exists, but Drupal's gating should + // actually prevent us from getting here otherwise. + if (!defined('CTOOLS_API_VERSION')) { + include_once drupal_get_path('module', 'ctools') . '/ctools.module'; + } + if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + $requirements['panels_ctools'] = array( + 'title' => $t('CTools API Version'), + 'value' => CTOOLS_API_VERSION, + 'severity' => REQUIREMENT_ERROR, + 'description' => t('The CTools API version is too old for Panels. Panels needs at least %version.', array('%version' => PANELS_REQUIRED_CTOOLS_API)) + ); + } + } + return $requirements; +} + +/** + * Check runtime requirements (status report). + */ +function panels_requirements_runtime() { + $requirements = array(); + $legacy = panels_get_legacy_state(); + $t = get_t(); + $state = $legacy->getStatus(); + if (empty($state)) { + $requirements['panels_legacy'] = array( + 'title' => $t('Panels operating normally'), + 'value' => NULL, + 'severity' => REQUIREMENT_OK, + 'description' => $t('Panels is operating normally - no out-of-date plugins or modules are forcing it into legacy mode'), + ); + } + else { + $description = $t("Panels is operating in Legacy mode due to the following issues:\n"); + + // Add the reasons why Panels is acting in legacy mode. + $list = array(); + foreach ($state as $values) { + $modules = array(); + foreach ($values['modules'] as $module => $type) { + $modules[] = array('data' => check_plain($module) . ' - ' . $type); + } + + $list[] = array('data' => $values['explanation'] ."\n" . theme('item_list', $modules)); + } + + $description .= theme('item_list', $list); + + $requirements['panels_legacy'] = array( + 'title' => $t('Panels operating in Legacy mode'), + 'value' => NULL, + 'severity' => REQUIREMENT_WARNING, + 'description' => $description, + ); + } + return $requirements; +} + +/** + * Implementation of hook_schema(). + */ +function panels_schema() { + // This should always point to our 'current' schema. This makes it relatively easy + // to keep a record of schema as we make changes to it. + return panels_schema_3(); +} + +/** + * Schema that adds the panels_layout table. + */ +function panels_schema_3() { + // Schema 3 is now locked. If you need to make changes, please create + // schema 4 and add them. + $schema = panels_schema_2(); + + $schema['panels_renderer_pipeline'] = array( + 'description' => 'Contains renderer pipelines for Panels. Each pipeline contains one or more renderers and access rules to select which renderer gets used.', + 'export' => array( + 'identifier' => 'pipeline', + 'bulk export' => TRUE, + 'primary key' => 'rpid', + 'api' => array( + 'owner' => 'panels', + 'api' => 'pipelines', + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), + 'fields' => array( + 'rpid' => array( + 'type' => 'serial', + 'description' => 'A database primary key to ensure uniqueness.', + 'not null' => TRUE, + 'no export' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this content. Used to identify it programmatically.', + ), + 'admin_title' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Administrative title for this pipeline.', + ), + 'admin_description' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Administrative description for this pipeline.', + 'object default' => '', + ), + 'weight' => array( + 'type' => 'int', + 'size' => 'small', + 'default' => 0, + ), + 'settings' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Serialized settings for the actual pipeline. The contents of this field are up to the plugin that uses it.', + 'serialize' => TRUE, + 'object default' => array(), + ), + ), + 'primary key' => array('rpid'), + ); + + $schema['panels_layout'] = array( + 'description' => 'Contains exportable customized layouts for this site.', + 'export' => array( + 'identifier' => 'layout', + 'bulk export' => TRUE, + 'primary key' => 'lid', + 'api' => array( + 'owner' => 'panels', + 'api' => 'layouts', + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), + 'fields' => array( + 'lid' => array( + 'type' => 'serial', + 'description' => 'A database primary key to ensure uniqueness.', + 'not null' => TRUE, + 'no export' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Unique ID for this content. Used to identify it programmatically.', + ), + 'admin_title' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Administrative title for this layout.', + ), + 'admin_description' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Administrative description for this layout.', + 'object default' => '', + ), + 'category' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'Administrative category for this layout.', + ), + 'plugin' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'The layout plugin that owns this layout.', + ), + 'settings' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Serialized settings for the actual layout. The contents of this field are up to the plugin that uses it.', + 'serialize' => TRUE, + 'object default' => array(), + ), + ), + 'primary key' => array('lid'), + ); + + return $schema; +} + +/** + * Schema that adds the title_pane field. + */ +function panels_schema_2() { + $schema = panels_schema_1(); + + $schema['panels_display']['fields']['title_pane'] = array( + 'type' => 'int', + 'default' => 0, + 'no export' => TRUE, + ); + + return $schema; +} + +/** + * Schema version 1 for Panels in D6. + * + * Schema v1 is now LOCKED; any changes should be done via panels_schema_2. + */ +function panels_schema_1() { + $schema = array(); + + $schema['panels_display'] = array( + 'export' => array( + 'object' => 'panels_display', + 'bulk export' => FALSE, + 'export callback' => 'panels_export_display', + 'can disable' => FALSE, + 'identifier' => 'display', + ), + 'fields' => array( + 'did' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'no export' => TRUE, + ), + 'layout' => array( + 'type' => 'varchar', + 'length' => '255', + 'default' => '', + ), + 'layout_settings' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'panel_settings' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'cache' => array( + 'type' => 'text', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'title' => array( + 'type' => 'varchar', + 'length' => '255', + 'default' => '', + ), + 'hide_title' => array( + 'type' => 'int', + 'size' => 'tiny', + 'default' => 0, + 'no export' => TRUE, + ), + ), + 'primary key' => array('did'), + ); + + $schema['panels_pane'] = array( + 'export' => array( + 'can disable' => FALSE, + 'identifier' => 'pane', + 'bulk export' => FALSE, + ), + 'fields' => array( + 'pid' => array( + 'type' => 'serial', + 'not null' => TRUE, + ), + 'did' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'no export' => TRUE, + ), + 'panel' => array( + 'type' => 'varchar', + 'length' => '32', + 'default' => '', + ), + 'type' => array( + 'type' => 'varchar', + 'length' => '32', + 'default' => '', + ), + 'subtype' => array( + 'type' => 'varchar', + 'length' => '64', + 'default' => '', + ), + 'shown' => array( + 'type' => 'int', + 'size' => 'tiny', + 'default' => 1, + ), + 'access' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'configuration' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'cache' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'style' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'css' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'extras' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'initial ' => array(), + ), + 'position' => array( + 'type' => 'int', + 'size' => 'small', + 'default' => 0, + ), + ), + 'primary key' => array('pid'), + 'indexes' => array( + 'did_idx' => array('did') + ), + ); + + return $schema; +} + +/** + * Implementation of hook_install(). + */ +function panels_install() { + drupal_install_schema('panels'); +} + +/** + * Implementation of hook_uninstall(). + */ +function panels_uninstall() { + drupal_uninstall_schema('panels'); +} + +function panels_update_1000() { + // Panels D6 2 had *no* update functions in it, so the schema version is + // completely wrong. If we run this update with no schema version, we + // were actually that version and we must therefore skip to the proper + // update. + if (db_table_exists('panels_pane')) { + $GLOBALS['SKIP_PANELS_UPDATES'] = TRUE; + return array(); + } + $ret = array(); + + $ret[] = update_sql("ALTER TABLE {panels_info} RENAME {panels_page}"); + $ret[] = update_sql("ALTER TABLE {panels_page} CHANGE COLUMN did pid int(10) NOT NULL DEFAULT 0;"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN did int(10) NOT NULL DEFAULT 0 AFTER pid"); + $ret[] = update_sql("UPDATE {panels_page} SET did = pid"); + + $max_pid = db_result(db_query("SELECT MAX(pid) FROM {panels_page}")); + if ($max_pid) { + $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{panels_page}_pid', $max_pid)"); + } + + $ret[] = update_sql("ALTER TABLE {panels_area} RENAME {panels_pane}"); + $ret[] = update_sql("ALTER TABLE {panels_pane} ADD COLUMN pid int(10) NOT NULL DEFAULT 0 FIRST"); + $ret[] = update_sql("ALTER TABLE {panels_pane} CHANGE area panel varchar(32)"); + $result = db_query("SELECT * FROM {panels_pane}"); + while ($pane = db_fetch_object($result)) { + $count++; + $ret[] = update_sql("UPDATE {panels_pane} SET pid = $count WHERE did = $pane->did AND panel = '$pane->panel' AND position = $pane->position"); + } + if ($count) { + $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{panels_pane}_pid', $count)"); + } + + $ret[] = update_sql(<<<EOT + CREATE TABLE {panels_display} ( + did INT(10) NOT NULL DEFAULT 0 PRIMARY KEY, + layout VARCHAR(32) + ) /*!40100 DEFAULT CHARACTER SET utf8 */ +EOT + ); + $result = db_query("SELECT did, layout FROM {panels_page}"); + $max_did = 0; + while ($display = db_fetch_object($result)) { + $ret[] = update_sql("INSERT INTO {panels_display} VALUES ($display->did, '$display->layout')"); + if ($display->did > $max_did) { + $max_did = $display->did; + } + } + $ret[] = update_sql("ALTER TABLE {panels_page} DROP COLUMN layout"); + if ($max_did) { + $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{panels_display}_did', $max_did)"); + } + return $ret; +} + +function panels_update_1001() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN no_blocks int(1)"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN menu int(1) DEFAULT 0"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN menu_tab int(1)"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN menu_tab_weight int(4)"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN menu_title varchar(255)"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN menu_tab_default int(1)"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN menu_tab_default_parent_type varchar(10)"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN menu_parent_title varchar(255)"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN menu_parent_tab_weight int(4)"); + return $ret; +} + +// Create a field for the layout settings +function panels_update_1002() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("ALTER TABLE {panels_display} ADD COLUMN layout_settings longtext"); + $ret[] = update_sql("ALTER TABLE {panels_pane} ADD COLUMN access varchar(128) AFTER type"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN css longtext AFTER css_id"); + return $ret; +} + +// Create a field for the panel settings. +function panels_update_1003() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("ALTER TABLE {panels_display} ADD COLUMN panel_settings longtext"); + return $ret; +} + +// Kept up updates from older versions of Panels 2 for D5 to smooth updates. +// Create a field for the panel settings. +// Renumbering to proper numbering scheme. +function panels_update_5204() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN name varchar(255) UNIQUE"); + $ret[] = update_sql("ALTER TABLE {panels_display} ADD COLUMN name varchar(255) UNIQUE"); + // Give all our panels a name. + $ret[] = update_sql("UPDATE {panels_page} SET name = CONCAT('panel_page_', pid)"); + $ret[] = update_sql("UPDATE {panels_display} SET name = CONCAT('display_', did)"); + return $ret; +} + +// Add the arguments field +function panels_update_5205() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN arguments longtext"); + return $ret; +} + +// Add a field so that panes can remember their subtype so we can retrieve +// context information about it. +function panels_update_5206() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("ALTER TABLE {panels_pane} ADD COLUMN subtype varchar(64)"); + return $ret; +} + +// Add fields for displays and extra contexts +function panels_update_5207() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN displays longtext"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN contexts longtext"); + return $ret; +} + +// Correct the mistaken {panels_display}_id when it should be {panels_display}_did +function panels_update_5208() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $count = db_result(db_query("SELECT MAX(did) FROM {panels_display}")); + $ret[] = update_sql("DELETE FROM {sequences} WHERE name = '{panels_display}_did'"); + $ret[] = update_sql("DELETE FROM {sequences} WHERE name = '{panels_display}_id'"); + if ($count) { + $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{panels_display}_did', + $count)"); + } + + return $ret; +} + +// Update argument, relationship and context code to be more correct. +function panels_update_5209() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN relationships longtext"); + $result = db_query("SELECT * FROM {panels_page}"); + + // This code removed due to call to panels_get_argument(). People with + // older versions will just have to suffer. + return $ret; + ctools_include('plugins', 'panels'); + + while ($page = db_fetch_object($result)) { + $args = unserialize($page->arguments); + $arguments = $ids = $keywords = array(); + if (!empty($args)) { + // Update each argument + foreach ($args as $id => $argument) { + $name = $argument['name']; + $info = panels_get_argument($name); + if (!$info) { + continue; + } + // Make sure the id is valid + if (empty($argument['id'])) { + if (empty($ids[$name])) { + $ids[$name] = 1; + } + else { + $ids[$name]++; + } + + $argument['id'] = $ids[$name]; + } + + // Give it an identifier if it doesn't already have one + if (empty($argument['identifier'])) { + $argument['identifier'] = $info['title'] . ($id > 1 ? ' ' . $id : ''); + } + + // Give it a unique keyword if it doesn't already have one + if (empty($argument['keyword'])) { + $keyword = $base = $info['keyword']; + $count = 0; + while (!empty($keywords[$keyword])) { + $keyword = $base . '_' . ++$count; + } + $keywords[$keyword] = TRUE; + $argument['keyword'] = $keyword; + } + $arguments[$id] = $argument; + } + } + // Move old relationships (stored as contexts) to relationships, where + // the belong + $rels = unserialize($page->contexts); + // Not resetting $keywords! + $relationships = $ids = array(); + if (!empty($rels)) { + foreach ($rels as $id => $relationship) { + $name = $relationship['name']; + $info = panels_get_relationship($name); + if (!$info) { + continue; + } + // Make sure the id is valid + if (empty($relationship['id'])) { + if (empty($ids[$name])) { + $ids[$name] = 1; + } + else { + $ids[$name]++; + } + + $relationship['id'] = $ids[$name]; + } + + // Give it an identifier if it doesn't already have one + if (empty($relationship['identifier'])) { + $relationship['identifier'] = $info['title'] . ($id > 1 ? ' ' . $id : ''); + } + + // Give it a unique keyword if it doesn't already have one + if (empty($relationship['keyword'])) { + $keyword = $base = $info['keyword']; + $count = 0; + while (!empty($keywords[$keyword])) { + $keyword = $base . '_' . ++$count; + } + $keywords[$keyword] = TRUE; + $relationship['keyword'] = $keyword; + } + $relationships[$id] = $relationship; + } + } + db_query("UPDATE {panels_page} " . + "SET arguments = '%s', " . + "relationships = '%s', " . + "contexts = '%s' " . + "WHERE pid = $page->pid", serialize($arguments), serialize($relationships), serialize(array()), $page->pid + ); + } + return $ret; +} + +function panels_update_5210() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + $ret[] = update_sql("UPDATE {system} SET weight = 10 WHERE name = 'panels'"); + return $ret; +} + +/** + * Force a menu update + */ +function panels_update_5211() { +// menu_rebuild(); + return array(); +} + +/** + * Add a field to store pane caching information. + */ +function panels_update_5213() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("ALTER TABLE {panels_pane} ADD COLUMN cache longtext AFTER configuration"); + $ret[] = update_sql("ALTER TABLE {panels_display} ADD COLUMN cache longtext AFTER panel_settings"); + break; + + case 'pgsql': + db_add_column($ret, 'panels_pane', 'cache', 'text'); + db_add_column($ret, 'panels_display', 'cache', 'text'); + } + return $ret; +} + +/** + * Create a new table for object caching. This isn't part of the cache + * system. + */ +function panels_update_5214() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + return $ret; + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql(<<<EOT + CREATE TABLE {panels_object_cache} ( + sid varchar(64), + did integer, + obj varchar(255), + timestamp integer, + data text, + KEY (sid, obj, did), + KEY (timestamp) + ) /*!40100 DEFAULT CHARACTER SET utf8 */ +EOT + ); + case 'pgsql': + } + return !empty($ret) ? $ret : $ret; +} + +/** + * Increase the size of the data column in the {panels_object_cache} table + * on MySQL. + * + * Also gets rid of some duplicate indexes resulting the CREATE TABLE queries + * in the install() of schema 5214 + */ +function panels_update_5215() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("ALTER TABLE {panels_pane} ADD PRIMARY KEY (pid)"); + break; + + case 'pgsql': + $ret[] = update_sql("ALTER TABLE {panels_pane} ADD PRIMARY KEY (pid)"); + } + return $ret; +} + +/** + * Adds the 'shown' field to the panels_pane table in order to accomodate + * the new show/hide panes feature. + */ +function panels_update_5216() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("ALTER TABLE {panels_pane} ADD COLUMN shown int(1) DEFAULT 1 AFTER subtype"); + $ret[] = update_sql("ALTER TABLE {panels_display} ADD COLUMN title varchar(128) AFTER cache"); + $ret[] = update_sql("ALTER TABLE {panels_display} ADD COLUMN hide_title int(1) AFTER title"); + $ret[] = update_sql("ALTER TABLE {panels_display} DROP COLUMN name"); + $ret[] = update_sql("ALTER TABLE {panels_pane} ADD COLUMN visibility text AFTER access"); + break; + + case 'pgsql': + db_add_column($ret, 'panels_pane', 'shown', 'tinyint', array('default' => 1)); + db_add_column($ret, 'panels_display', 'title', 'varchar(128)'); + db_add_column($ret, 'panels_display', 'hide_title', 'tinyint', array('default' => 0)); + $ret = update_sql("ALTER TABLE {panels_display} DROP name"); + db_add_column($ret, 'panels_pane', 'visibility', 'text'); + } + return $ret; +} + +/** + * Add the switcher fields to the database + */ +function panels_update_5217() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN switcher_type varchar(128) AFTER no_blocks"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN switcher_name varchar(128) AFTER no_blocks"); + $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN switcher_options longtext AFTER switcher_type"); + break; + + case 'pgsql': + db_add_column($ret, 'panels_page', 'switcher_type', 'varchar(128)'); + db_add_column($ret, 'panels_page', 'switcher_name', 'varchar(128)'); + db_add_column($ret, 'panels_page', 'switcher_options', 'text'); + } + return $ret; +} + + +/** + * Oversight in 5216: 'tinyint' is not a field type in pgsql; the type we wanted + * was 'smallint.' + */ +function panels_update_5218() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = array('success' => TRUE, 'query' => t('Update #5218 only has changes for PostgreSQL. There are no updates for MySQL databases - since you\'re running MySQL, you should consider this update successful.')); + break; + + case 'pgsql': + db_add_column($ret, 'panels_pane', 'shown', 'smallint', array('default' => 1)); + db_add_column($ret, 'panels_display', 'hide_title', 'smallint', array('default' => 0)); + $ret[] = array('success' => TRUE, 'query' => t('You can disregard failed attempts to add new columns in update #5216 as long as the two queries preceding this text were successful.')); + } + return $ret; +} + +/** + * Update from 5.x v2 + */ +function panels_update_5299() { + if (!empty($GLOBALS['SKIP_PANELS_UPDATES'])) { + return array(); + } + $ret = array(); + // Fetch schema version 1. + $schema = panels_schema_1(); + + // Certain really old versions of Panels had errors that would cause invalid + // panes to be written. This wipes them so that the conversion won't fail: + $ret[] = update_sql("DELETE FROM {panels_pane} WHERE pid = 0"); + + // update pid and did to be serial + db_drop_primary_key($ret, 'panels_pane'); + db_change_field($ret, 'panels_pane', 'pid', 'pid', $schema['panels_pane']['fields']['pid'], array('primary key' => array('pid'))); + db_drop_primary_key($ret, 'panels_display'); + db_change_field($ret, 'panels_display', 'did', 'did', $schema['panels_display']['fields']['did'], array('primary key' => array('did'))); + + drupal_set_message(t('Please note that the Panels upgrade from Drupal 5 to Drupal 6 is far from perfect, especially where Views and CCK are involved. Please check all your panels carefully and compare them against the originals. You may need to do some rework to regain your original functionality.')); + + return $ret; +} + +/** + * Update from 6.x v2. + */ +function panels_update_6290() { + $ret = array(); + if (!module_exists('panels')) { + $ret['#abort'] = array('success' => FALSE, 'query' => t('The Panels module cannot be updated while disabled. If you wish to update Panels, please enable it. If you do not wish to update Panels, please uninstall it.')); + return $ret; + } + + // Fetch schema version 1. + $schema = panels_schema_1(); + + // Update size of pane 'access' field. + db_change_field($ret, 'panels_pane', 'access', 'access', $schema['panels_pane']['fields']['access']); + + // Remove the no longer used visibility field + if (db_column_exists('panels_pane', 'visibility')) { + db_drop_field($ret, 'panels_pane', 'visibility'); + } + + // Remove panels_object_cache table + if (db_table_exists('panels_object_cache')) { + db_drop_table($ret, 'panels_object_cache'); + } + + // Doublecheck that ctools is enabled. If not, automatically disable the module. + if (!module_exists('ctools')) { + // Try to enable it: + drupal_install_modules(array('ctools')); + + // If that fails, shut off all Panels. + if (!module_exists('ctools')) { + drupal_set_message(t('Panels now requires the Chaos Tool Suite (ctools) module to function. Panels has been disabled until you can add this module.')); + module_disable(array('panels', 'panels_mini', 'panels_export', 'panels_node', 'panels_simple_cache')); + } + } + + if (!module_exists('page_manager') && db_table_exists('panels_page')) { + drupal_set_message('Page manager module has been automatically enabled to replace the Panels pages module.'); + drupal_install_modules(array('page_manager')); + } + + $ret[] = update_sql("DELETE FROM {system} WHERE name IN ('panels_page', 'panels_views')"); + + return $ret; +} + +/** + * Special update function for the alpha2 to alpha3 transition after + * I messed it up. + */ +function panels_update_6291() { + $ret = array(); + if (!module_exists('panels')) { + $ret['#abort'] = array('success' => FALSE, 'query' => t('The Panels module cannot be updated while disabled. If you wish to update Panels, please enable it. If you do not wish to update Panels, please uninstall it.')); + return $ret; + } + + // Fetch schema version 1. + $schema = panels_schema_1(); + + + // Add some new fields + db_add_field($ret, 'panels_pane', 'style', $schema['panels_pane']['fields']['style']); + db_add_field($ret, 'panels_pane', 'css', $schema['panels_pane']['fields']['css']); + db_add_field($ret, 'panels_pane', 'extras', $schema['panels_pane']['fields']['extras']); + + return $ret; +} + +/** + * Update panels pane fields using batch API. + */ +function panels_update_6292(&$sandbox) { + $ret = array(); + if (!module_exists('panels')) { + $ret['#abort'] = array('success' => FALSE, 'query' => t('The Panels module cannot be updated while disabled. If you wish to update Panels, please enable it. If you do not wish to update Panels, please uninstall it.')); + return $ret; + } + + if (!isset($sandbox['progress'])) { + $sandbox['progress'] = 0; + // We'll -1 to disregard the uid 0... + $sandbox['max'] = db_result(db_query('SELECT COUNT(*) FROM {panels_pane}')); + } + + // configuration + $result = db_query_range("SELECT pid, access, configuration FROM {panels_pane} ORDER BY pid ASC", $sandbox['progress'], 20); + while ($pane = db_fetch_object($result)) { + // access + if (!empty($pane->access)) { + $rids = explode(', ', $pane->access); + // For safety, eliminate any non-numeric rids, as we occasionally had + // problems with nulls and such getting in here: + foreach ($rids as $id => $rid) { + if (!is_numeric($rid)) { + unset($rids[$id]); + } + } + + if (empty($rids)) { + $pane->access = array(); + } + else { + // The old access style was just a role based system, so let's convert + // it to that. + $pane->access = array( + 'plugins' => array( + array( + 'name' => 'role', + 'context' => 'logged-in-user', + 'settings' => array( + 'rids' => array_values($rids), + ) + ), + ), + ); + } + } + else { + $pane->access = array(); + } + + // Move style from configuration. + $pane->configuration = unserialize($pane->configuration); + $pane->style = array(); + if (!empty($pane->configuration['style'])) { + $pane->style['style'] = $pane->configuration['style']; + unset($pane->configuration['style']); + } + + $pane->css = array(); + // Move css configuration from configuration + if (isset($pane->configuration['css_id'])) { + $pane->css['css_id'] = $pane->configuration['css_id']; + unset($pane->configuration['css_id']); + } + + if (isset($pane->configuration['css_class'])) { + $pane->css['css_class'] = $pane->configuration['css_class']; + unset($pane->configuration['css_class']); + } + + // Make sure extras is an array. This isn't used by anything in Panels + // yet, so an empty array is just fine. + $pane->extras = array(); + db_query("UPDATE {panels_pane} SET " . + "access = '%s', css = '%s', style = '%s', configuration = '%s', extras = '%s'" . + " WHERE pid = %d", + serialize($pane->access), + serialize($pane->css), + serialize($pane->style), + serialize($pane->configuration), + serialize($pane->extras), + $pane->pid); + + $sandbox['progress']++; + } + + $ret['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); + if ($ret['#finished'] === 1) { + $ret[] = array('success' => TRUE, 'query' => t('Panel panes were updated')); + } + return $ret; +} + +/** + * Update panels display fields using batch API. + */ +function panels_update_6293(&$sandbox) { + $ret = array(); + if (!module_exists('panels')) { + $ret['#abort'] = array('success' => FALSE, 'query' => t('The Panels module cannot be updated while disabled. If you wish to update Panels, please enable it. If you do not wish to update Panels, please uninstall it.')); + return $ret; + } + + if (!isset($sandbox['progress'])) { + $sandbox['progress'] = 0; + // We'll -1 to disregard the uid 0... + $sandbox['max'] = db_result(db_query('SELECT COUNT(*) FROM {panels_display}')); + } + + // configuration + $result = db_query_range("SELECT did, panel_settings FROM {panels_display} ORDER BY did ASC", $sandbox['progress'], 20); + while ($display = db_fetch_object($result)) { + if (empty($display->panel_settings)) { + $display->panel_settings = array(); + } + else { + $display->panel_settings = unserialize($display->panel_settings); + if (!is_array($display->panel_settings)) { + $display->panel_settings = array(); + } + } + + if (isset($display->panel_settings['panel'])) { + foreach ($display->panel_settings['panel'] as $key => $settings) { + $display->panel_settings[$key] = $settings; + } + unset($display->panel_settings['panel']); + } + + if (isset($display->panel_settings['individual'])) { + unset($display->panel_settings['individual']); + } + + db_query("UPDATE {panels_display} SET " . + "panel_settings = '%s'" . + " WHERE did = %d", + serialize($display->panel_settings), + $display->did); + + $sandbox['progress']++; + } + + $ret['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); + if ($ret['#finished'] === 1) { + $ret[] = array('success' => TRUE, 'query' => t('Panel displays were updated')); + } + return $ret; +} + +/** + * Establish a baseline schema version for 6.x-3.x + */ +function panels_update_6300() { + return array(); +} + +function panels_update_6302() { + $ret = array(); + if (!module_exists('panels')) { + $ret['#abort'] = array('success' => FALSE, 'query' => t('The Panels module cannot be updated while disabled. If you wish to update Panels, please enable it. If you do not wish to update Panels, please uninstall it.')); + return $ret; + } + + if (!module_exists('page_manager') && db_table_exists('panels_page')) { + $ret['#abort'] = array('success' => FALSE, 'query' => t('Conversion of panels pages cannot be completed without page manager module from CTools installed. Please install CTools, activate page manager, and attempt the update again.')); + return $ret; + } + + if (!db_table_exists('panels_page')) { + return $ret; + } + + // Store the node edit handlers because we merged the edit/add path and we + // need to be able to keep these together to make sure the names work ok. + $node_edit_handlers = array(); + page_manager_get_task('page'); + $result = db_query("SELECT * FROM {panels_page}"); + while ($p = db_fetch_object($result)) { + $page = page_manager_page_new(); + $page->default_handlers = array(); + // Should we check for uniqueness here? It doesn't seem really + // plausible that there could be page manager pages already. + $page->name = $p->name; + $page->task = 'page'; // could become custom later. + $page->subtask = $p->name; + $page->admin_title = $p->name; + $page->path = $p->path; + // convert access + if (!empty($p->access)) { + $rids = explode(', ', $p->access); + // For safety, eliminate any non-numeric rids, as we occasionally had + // problems with nulls and such getting in here: + foreach ($rids as $id => $rid) { + if (!is_numeric($rid)) { + unset($rids[$id]); + } + } + + if (empty($rids)) { + $page->access = array(); + } + else { + // The old access style was just a role based system, so let's convert + // it to that. + $page->access = array( + 'plugins' => array( + array( + 'name' => 'role', + 'context' => 'logged-in-user', + 'settings' => array( + 'rids' => array_values($rids), + ) + ), + ), + ); + } + } + + // Convert menu stuff. + $page->menu = array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + 'name' => 'navigation', + 'parent' => array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + 'name' => 'navigation', + ), + ); + + if ($p->menu) { + if ($p->menu_tab) { + if ($p->menu_tab_default) { + $page->menu['type'] = 'default tab'; + $page->menu['parent']['type'] = $p->menu_tab_default_parent_type; + $page->menu['parent']['title'] = $p->menu_parent_title; + $page->menu['parent']['weight'] = $p->menu_parent_tab_weight; + } + else { + $page->menu['type'] = 'tab'; + } + } + else { + $page->menu['type'] = 'normal'; + } + + $page->menu['title'] = $p->menu_title; + $page->menu['weight'] = $p->menu_tab_weight; + } + + $page->conf = array(); + $displays = unserialize($p->displays); + $arguments = unserialize($p->arguments); + + foreach ($arguments as $id => $argument) { + $page->arguments[$argument['keyword']] = array( + 'name' => $argument['name'], + 'identifier' => $argument['identifier'], + 'title' => $argument['title'], + 'id' => $argument['id'], + 'settings' => isset($argument['argument_settings']) ? $argument['argument_settings'] : array(), + ); + + $match = FALSE; + $bits = explode('/', $page->path); + foreach ($bits as $pos => $bit) { + if ($bit == '%') { + $bits[$pos] = '%' . $argument['keyword']; + $match = TRUE; + $page->path = implode('/', $bits); + break; + } + } + + if (!$match) { + if ($argument['default'] == '404') { + $page->path .= '/%' . $argument['keyword']; + } + else { + $page->path .= '/!' . $argument['keyword']; + } + } + + // save this for later use. + $arguments[$id]['context'] = 'argument_' . $argument['name'] . '_' . $argument['id']; + } + + // Reset the task type here if it's one of our overrides. This ensures + // that we get the right names. + switch ($p->path) { + case 'node/%': + $page->task = 'node_view'; + $page->subtask = ''; + variable_set('page_manager_node_view_disabled', FALSE); + break; + case 'node/add/%': + // It seems nearly impossible to actually upgrade this properly. + continue; + case 'node/%/edit': + // Could we get conflicts here if they had both? + $page->task = 'node_edit'; + $page->subtask = ''; + variable_set('page_manager_node_edit_disabled', FALSE); + break; + case 'taxonomy/term': + case 'taxonomy/term/%': + $page->task = 'term_view'; + $page->subtask = ''; + if ($arguments[0]['name'] == 'term') { + variable_set('page_manager_term_view_type', 'single'); + } + variable_set('page_manager_term_view_disabled', FALSE); + break; + case 'user/%': + $page->task = 'user_view'; + $page->subtask = ''; + variable_set('page_manager_user_view_disabled', FALSE); + break; + // There is no default here. + } + + if (empty($displays)) { + // only one display on this panel, mak + $cache = new stdClass(); + if ($page->task != 'node_edit') { + $cache->handlers = array(); + } + else { + $cache->handlers = $node_edit_handlers; + } + _panels_update_create_handler($page, $p, NULL, array('did' => $p->did, 'title' => t('Panel')), $arguments, 0, $cache); + $page->default_handlers = $cache->handlers; + } + else { + // for each display we need to create a new handler. + $weight = 0; + $cache = new stdClass(); + if ($page->task != 'node_edit') { + $cache->handlers = array(); + } + else { + $cache->handlers = $node_edit_handlers; + $weight = count($cache->handlers) + 1; + } + foreach ($displays as $origin => $info) { + if (!isset($info['argument_id'])) { + $info['argument_id'] = 0; + } + + _panels_update_create_handler($page, $p, $origin, $info, $arguments, $weight++, $cache); + } + + // Also add the primary display as a default with no selector. +// _panels_update_create_handler($page, $p, NULL, array('did' => $p->did, 'title' => t('Default')), $arguments, $weight++, $cache); + $page->default_handlers = $cache->handlers; + } + + if ($page->task != 'page') { + // just save the handlers. + foreach ($cache->handlers as $name => $handler) { + page_manager_save_task_handler($handler); + + // Keep all node edit handlers for later use. + if ($page->task == 'node_edit') { + $node_edit_handlers[$name] = $handler; + } + } + } + else { + page_manager_page_save($page); + } + } + + $ret[] = update_sql("DROP TABLE {panels_page}"); + + // Update a couple of pane types that changed and are easily moved: + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("UPDATE {panels_pane} SET type = CONCAT(type, '_', subtype) WHERE type = 'node_form'"); + break; + + case 'pgsql': + $ret[] = update_sql("UPDATE {panels_pane} SET type = type || '_' || subtype WHERE type = 'node_form'"); + } + $ret[] = update_sql("UPDATE {panels_pane} SET type = 'node_form_path' WHERE type = 'node_form_url_path'"); + + if (module_exists('ctools') && !module_exists('views_content') && db_result(db_query("SELECT pid FROM {panels_pane} WHERE type = 'views'"))) { + drupal_install_modules(array('views_content')); + } + + return $ret; +} + +function _panels_update_create_handler($page, $p, $origin, $info, $arguments, $weight, &$cache) { + $task = page_manager_get_task($page->task); + $task_name = 'page-' . $page->name; + $plugin = page_manager_get_task_handler('panel_context'); + $handler = page_manager_new_task_handler($plugin); + + $handler->weight = $weight; + $handler->task = $page->task; + if ($page->task == 'page') { + $handler->subtask = $page->name; + } + $handler->export_type = EXPORT_IN_DATABASE; + $handler->type = t('Normal'); + + $handler->name = page_manager_handler_get_name($task_name, $cache->handlers, $handler); + + $handler->conf['css'] = $p->css; + $handler->conf['css_id'] = $p->css_id; + $handler->conf['no_blocks'] = $p->no_blocks; + if (!empty($info['did']) && is_numeric($info['did'])) { + $handler->conf['did'] = $info['did']; + } + else { + $d = panels_load_display($p->did); + if ($d) { + $display_code = panels_export_display($d); + eval($display_code); + + $handler->conf['did'] = 'new'; + $handler->conf['display'] = $display; + } + } + $handler->conf['title'] = !empty($info['title']) ? $info['title'] : ''; + $handler->conf['contexts'] = unserialize($p->contexts); + $handler->conf['relationships'] = unserialize($p->relationships); + + if ($origin && strpos($origin, '-')) { + $handler->conf['access'] = array( + 'logic' => 'and', + 'plugins' => array(), + ); + + // Only 4 types of arguments supported having their own displays: + // nid, node_add_form, node_edit_form and term. 3 of those simply used + // node type and the last simply used vocabulary. + list($junk, $key) = explode('-', $origin); + if ($key && $key != 'default') { + if ($arguments[$info['argument_id']]['name'] == 'term') { + $handler->conf['access']['plugins'][] = array( + 'name' => 'term_vocabulary', + 'context' => $arguments[$info['argument_id']]['context'], + 'settings' => array( + 'vids' => array($key), + ), + ); + } + else { + $handler->conf['access']['plugins'][] = array( + 'name' => 'node_type', + 'context' => $arguments[$info['argument_id']]['context'], + 'settings' => array( + 'type' => array($key), + ), + ); + } + } + else { + // make sure defaults float to the bottom: + $handler->weight += 100; + } + } + $cache->handlers[$handler->name] = $handler; + + return $handler; +} + +/** + * Ensure the panels_simple_cache module does not exist. + */ +function panels_update_6303() { + $ret = array(); + if (module_exists('panels_simple_cache')) { + drupal_set_message(t('Your installation contains a module that no longer exists. When updating modules, you should always remove the module directory first, then replace it with the new code. The "Panels Simple Cache" module is being automatically disabled for you. Please do not re-enable it as it will cause your system to crash.')); + $ret[] = update_sql("DELETE FROM {system} WHERE name = 'panels_simple_cache'"); + } + + return $ret; +} + +/** + * Ensure that users are informed about the page manager module. + */ +function panels_update_6304() { + if (!module_exists('page_manager')) { + drupal_set_message(t('The delegator module has been replaced by the Page Manager module. You should enable the page manager module to ensure that any panel pages you have will not be lost.')); + } + + return array(); +} + +/** + * Add the title_pane field. + */ +function panels_update_6305() { + $ret = array(); + + // Fetch schema version 2. + $schema = panels_schema_2(); + + // Add new field + db_add_field($ret, 'panels_display', 'title_pane', $schema['panels_display']['fields']['title_pane']); + + return $ret; +} + +/** + * Drop a table that should have been gone long ago. + */ +function panels_update_6306() { + $ret = array(); + + if (db_table_exists('panels_page_router_store')) { + db_drop_table($ret, 'panels_page_router_store'); + } + + return $ret; +} + +/** + * This update function does nothing, it was committed in error and is + * left in to prevent update problems. + */ +function panels_update_6307() { + return array(); +} + +/** + * Add the panels_layout table + */ +function panels_update_6308() { + $ret = array(); + + // Schema 3 is locked and should not be changed. + $schema = panels_schema_3(); + + db_create_table($ret, 'panels_layout', $schema['panels_layout']); + return $ret; +} + +/** + * Add the panels_renderer_pipeline table + */ +function panels_update_6309() { + $ret = array(); + + // Schema 3 is locked and should not be changed. + $schema = panels_schema_3(); + + db_create_table($ret, 'panels_renderer_pipeline', $schema['panels_renderer_pipeline']); + return $ret; +} + +/** + * Move stylizer data from Panels to CTools. + */ +function panels_update_6310() { + $ret = array(); + // load the module files, if possible + if (!defined('PANELS_REQUIRED_CTOOLS_API')) { + include_once drupal_get_path('module', 'panels') . '/panels.module'; + } + if (!defined('CTOOLS_API_VERSION')) { + include_once drupal_get_path('module', 'ctools') . '/ctools.module'; + } + // Safety: go away if CTools is not at an appropriate version. + if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + $ret['#abort'] = array('success' => FALSE, 'query' => t('Panels cannot be updated because CTools 1.7 (API v1.7.2) is required. Please update CTools and then try update.php again.')); + return $ret; + } + + // Enable the stylizer module to make everything as seamless as possible. + drupal_install_modules(array('stylizer')); + return $ret; +} + +/** + * Change panels_display.layout to match the size of panels_layout.name. + */ +function panels_update_6311() { + $ret = array(); + + // Clear the schema cache so the change is picked up. + cache_clear_all('schema', 'cache'); + + // Load the schema. + $schema = panels_schema(); + $table = 'panels_display'; + $field = 'layout'; + $spec = $schema[$table]['fields'][$field]; + + // Re-define the column. + db_change_field($ret, $table, $field, $field, $spec); + + $ret[] = array('success' => TRUE, 'query' => t('Changed the panels_display.layout field to the correct size.')); + + return $ret; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels.module b/drupal/sites/default/boinc/modules/contrib/panels/panels.module new file mode 100644 index 0000000000000000000000000000000000000000..d24b9bca4dccef40ac958d27211743b3a34b6c60 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels.module @@ -0,0 +1,1685 @@ +<?php + +/** + * @file panels.module + * + * Core functionality for the Panels engine. + */ + +define('PANELS_REQUIRED_CTOOLS_API', '1.8'); + +define('PANELS_TITLE_FIXED', 0); // Hide title use to be true/false. So false remains old behavior. +define('PANELS_TITLE_NONE', 1); // And true meant no title. +define('PANELS_TITLE_PANE', 2); // And this is the new behavior, where the title field will pick from a pane. + +/** + * Returns the API version of Panels. This didn't exist in 1. + * + * @return An array with the major and minor versions + */ +function panels_api_version() { + return array(3, 1); +} + +// -------------------------------------------------------------------------- +// Core Drupal hook implementations + +/** + * Implementation of hook_theme() + */ +function panels_theme() { + // Safety: go away if CTools is not at an appropriate version. + if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + return array(); + } + + $theme = array(); + $theme['panels_layout_link'] = array( + 'arguments' => array('title', 'id', 'image', 'link'), + ); + $theme['panels_layout_icon'] = array( + 'arguments' => array('id', 'image', 'title' => NULL), + ); + $theme['panels_pane'] = array( + 'arguments' => array('output' => array(), 'pane' => array(), 'display' => array()), + 'path' => drupal_get_path('module', 'panels') . '/templates', + 'template' => 'panels-pane', + ); + $theme['panels_common_content_list'] = array( + 'arguments' => array('display'), + 'file' => 'includes/common.inc', + ); + $theme['panels_render_display_form'] = array( + 'arguments' => array('form' => NULL), + ); + + $theme['panels_dashboard'] = array( + 'arguments' => array(), + 'path' => drupal_get_path('module', 'panels') . '/templates', + 'file' => '../includes/callbacks.inc', + 'template' => 'panels-dashboard', + ); + + $theme['panels_dashboard_link'] = array( + 'arguments' => array('link' => array()), + 'path' => drupal_get_path('module', 'panels') . '/templates', + 'file' => '../includes/callbacks.inc', + 'template' => 'panels-dashboard-link', + ); + + $theme['panels_dashboard_block'] = array( + 'arguments' => array('block' => array()), + 'path' => drupal_get_path('module', 'panels') . '/templates', + 'file' => '../includes/callbacks.inc', + 'template' => 'panels-dashboard-block', + ); + + // We don't need layout and style themes in maintenance mode. + // Disabling this: See http://drupal.org/node/979912 for information. +// if (defined('MAINTENANCE_MODE')) { +// return $theme; +// } + + // Register layout and style themes on behalf of all of these items. + ctools_include('plugins', 'panels'); + + // No need to worry about files; the plugin has to already be loaded for us + // to even know what the theme function is, so files will be auto included. + $layouts = panels_get_layouts(); + foreach ($layouts as $name => $data) { + foreach (array('theme', 'admin theme') as $callback) { + if (!empty($data[$callback])) { + $theme[$data[$callback]] = array( + 'arguments' => array('css_id' => NULL, 'content' => NULL, 'settings' => NULL, 'display' => NULL, 'layout' => NULL, 'renderer' => NULL), + 'path' => $data['path'], + 'file' => $data['file'], + ); + + // if no theme function exists, assume template. + if (!function_exists("theme_$data[theme]")) { + $theme[$data[$callback]]['template'] = str_replace('_', '-', $data[$callback]); + $theme[$data[$callback]]['file'] = $data['file']; // for preprocess. + } + } + } + } + + $styles = panels_get_styles(); + foreach ($styles as $name => $data) { + if (!empty($data['render pane'])) { + $theme[$data['render pane']] = array( + 'arguments' => array('output' => NULL, 'pane' => NULL, 'display' => NULL, 'style' => NULL), + 'path' => $data['path'], + 'file' => $data['file'], + ); + } + // If we're in legacy mode, include the old callback key for legacy styles. + if (variable_get('panels_legacy_rendering_mode', TRUE)) { + if (!empty($data['render panel'])) { + $theme[$data['render panel']] = array( + 'arguments' => array('display' => NULL, 'panel_id' => NULL, 'panes' => NULL, 'settings' => NULL, 'style' => NULL), + 'path' => $data['path'], + 'file' => $data['file'], + ); + } + } + if (!empty($data['render region'])) { + $theme[$data['render region']] = array( + 'arguments' => array('display' => NULL, 'region_id' => NULL, 'panes' => NULL, 'settings' => NULL, 'style' => NULL), + 'path' => $data['path'], + 'file' => $data['file'], + ); + } + + if (!empty($data['hook theme'])) { + if (is_array($data['hook theme'])) { + $theme += $data['hook theme']; + } + else if (function_exists($data['hook theme'])) { + $data['hook theme']($theme, $data); + } + } + } + + return $theme; +} + +/** + * Implementation of hook_menu + */ +function panels_menu() { + // Safety: go away if CTools is not at an appropriate version. + if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + return array(); + } + $items = array(); + + // Base AJAX router callback. + $items['panels/ajax'] = array( + 'access arguments' => array('access content'), + 'page callback' => 'panels_ajax_router', + 'type' => MENU_CALLBACK, + ); + + $admin_base = array( + 'file' => 'includes/callbacks.inc', + 'access arguments' => array('use panels dashboard'), + ); + // Provide a nice location for a panels admin panel. + $items['admin/build/panels'] = array( + 'title' => 'Panels', + 'page callback' => 'panels_admin_page', + 'description' => 'Get a bird\'s eye view of items related to Panels.', + ) + $admin_base; + + $items['admin/build/panels/dashboard'] = array( + 'title' => 'Dashboard', + 'page callback' => 'panels_admin_page', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ) + $admin_base; + + $items['admin/build/panels/settings'] = array( + 'title' => 'Settings', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('panels_admin_settings_page'), + 'type' => MENU_LOCAL_TASK, + ) + $admin_base; + + $items['admin/build/panels/settings/general'] = array( + 'title' => 'General', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('panels_admin_settings_page'), + 'access arguments' => array('administer page manager'), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ) + $admin_base; + + if (module_exists('page_manager')) { + $items['admin/build/panels/settings/panel-page'] = array( + 'title' => 'Panel pages', + 'page callback' => 'panels_admin_panel_context_page', + 'type' => MENU_LOCAL_TASK, + 'weight' => -10, + ) + $admin_base; + } + + ctools_include('plugins', 'panels'); + $layouts = panels_get_layouts(); + foreach ($layouts as $name => $data) { + if (!empty($data['hook menu'])) { + if (is_array($data['hook menu'])) { + $items += $data['hook menu']; + } + else if (function_exists($data['hook menu'])) { + $data['hook menu']($items, $data); + } + } + } + + + return $items; +} + +/** + * Menu loader function to load a cache item for Panels AJAX. + * + * This load all of the includes needed to perform AJAX, and loads the + * cache object and makes sure it is valid. + */ +function panels_edit_cache_load($cache_key) { + ctools_include('display-edit', 'panels'); + ctools_include('plugins', 'panels'); + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + + return panels_edit_cache_get($cache_key); +} + +/** + * Implementation of hook_init() + */ +function panels_init() { + // Safety: go away if CTools is not at an appropriate version. + if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + if (user_access('administer site configuration')) { + drupal_set_message(t('Panels is enabled but CTools is out of date. All Panels modules are disabled until CTools is updated. See the status page for more information.'), 'error'); + } + return; + } + + ctools_add_css('panels', 'panels'); + ctools_add_js('panels', 'panels'); +} + +/** + * Implementation of hook_perm + */ +function panels_perm() { + return array( + 'view all panes', + 'view pane admin links', + 'administer pane visibility', + 'administer pane access', + 'administer advanced pane settings', + 'administer panels layouts', + 'use panels caching features', + 'use panels dashboard', + 'use panels in place editing', + ); +} + +/** + * Implementation of hook_flush_caches(). + * + * We implement this so that we can be sure our legacy rendering state setting + * in $conf is updated whenever caches are cleared. + */ +function panels_flush_caches() { + $legacy = panels_get_legacy_state(); + $legacy->determineStatus(); +} + +// --------------------------------------------------------------------------- +// CTools hook implementations +// +// These aren't core Drupal hooks but they are just as important. + +/** + * Implementation of hook_ctools_plugin_directory() to let the system know + * we implement task and task_handler plugins. + */ +function panels_ctools_plugin_directory($module, $plugin) { + // Safety: go away if CTools is not at an appropriate version. + if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + return; + } + if ($module == 'page_manager' || $module == 'panels' || $module == 'ctools') { + return 'plugins/' . $plugin; + } +} + +/** + * Inform CTools that the layout plugin can be loaded from themes. + */ +function panels_ctools_plugin_layouts() { + return array( + 'load themes' => TRUE, + 'use hooks' => TRUE, + 'process' => 'panels_layout_process', + 'child plugins' => TRUE, + ); +} + +/** + * Ensure a layout has a minimal set of data. + */ +function panels_layout_process(&$plugin) { + $plugin += array( + 'category' => t('Miscellaneous'), + 'description' => '', + ); +} + +/** + * Inform CTools that the style plugin can be loaded from themes. + */ +function panels_ctools_plugin_styles() { + return array( + 'load themes' => TRUE, + 'use hooks' => TRUE, + 'process' => 'panels_plugin_styles_process', + 'child plugins' => TRUE, + ); +} + +/** + * Implementation of hook_ctools_plugin_api(). + * + * Inform CTools about version information for various plugins implemented by + * Panels. + * + * @param string $owner + * The system name of the module owning the API about which information is + * being requested. + * @param string $api + * The name of the API about which information is being requested. + */ +function panels_ctools_plugin_api($owner, $api) { + if ($owner == 'panels' && $api == 'styles') { + // As of 6.x-3.6, Panels has a slightly new system for style plugins. + return array('version' => 2.0); + } + + if ($owner == 'panels' && $api == 'pipelines') { + return array( + 'version' => 1, + 'path' => drupal_get_path('module', 'panels') . '/includes', + ); + } +} + +/** + * Implementation of hook_views_api(). + */ +function panels_views_api() { + return array( + 'api' => 2, + 'path' => drupal_get_path('module', 'panels') . '/plugins/views', + ); +} + +/** + * Perform additional processing on a style plugin. + * + * Currently this is only being used to apply versioning information to style + * plugins in order to ensure the legacy renderer passes the right type of + * parameters to a style plugin in a hybrid environment of both new and old + * plugins. + * + * @see _ctools_process_data() + * + * @param array $plugin + * The style plugin that is being processed. + * @param array $info + * The style plugin type info array. + */ +function panels_plugin_styles_process(&$plugin, $info) { + $plugin += array( + 'weight' => 0, + ); + + $compliant_modules = ctools_plugin_api_info('panels', 'styles', 2.0, 2.0); + $plugin['version'] = empty($compliant_modules[$plugin['module']]) ? 1.0 : $compliant_modules[$plugin['module']]['version']; +} + +/** + * Declare what style types Panels uses. + */ +function panels_ctools_style_base_types() { + return array( + 'region' => array( + 'title' => t('Panel region'), + 'preview' => 'panels_stylizer_region_preview', + 'theme arguments' => array('settings' => NULL, 'classes' => NULL, 'content' => NULL), + ), + 'pane' => array( + 'title' => t('Panel pane'), + 'preview' => 'panels_stylizer_pane_preview', + 'theme arguments' => array('settings' => NULL, 'content' => NULL, 'pane' => NULL, 'display' => NULL), + ), + ); +} + +function panels_stylizer_lipsum() { + return " + <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus at velit dolor. Donec egestas tellus sit amet urna rhoncus adipiscing. Proin nec porttitor sem. Maecenas aliquam, purus nec tempus dignissim, nulla arcu aliquam diam, non tincidunt massa ante vel dolor. Aliquam sapien sapien, tincidunt id tristique at, pretium sagittis libero.</p> + + <p>Nulla facilisi. Curabitur lacinia, tellus sed tristique consequat, diam lorem scelerisque felis, at dictum purus augue facilisis lorem. Duis pharetra dignissim rutrum. Curabitur ac elit id dui dapibus tincidunt. Nulla eget sem quam, non eleifend eros. Cras porttitor tempus lectus ac scelerisque. Curabitur vehicula bibendum lorem, vitae ornare ligula venenatis ut.</p> + "; +} + +/** + * Generate a preview given the current settings. + */ +function panels_stylizer_region_preview($plugin, $settings) { + ctools_stylizer_add_css($plugin, $settings); + return theme($plugin['theme'], $settings, ctools_stylizer_get_css_class($plugin, $settings), panels_stylizer_lipsum()); +} + +/** + * Generate a preview given the current settings. + */ +function panels_stylizer_pane_preview($plugin, $settings) { + ctools_stylizer_add_css($plugin, $settings); + $pane = new stdClass(); + + $content = new stdClass; + $content->title = t('Lorem ipsum'); + $content->content = panels_stylizer_lipsum(); + $content->type = 'dummy'; + $content->subtype = 'dummy'; + + $content->css_class = ctools_stylizer_get_css_class($plugin, $settings); + + $display = new panels_display(); + + if (!empty($plugin['theme'])) { + return theme($plugin['theme'], $settings, $content, $pane, $display); + } + else { + return theme('panels_pane', $content, $pane, $display); + } +} + +// --------------------------------------------------------------------------- +// Panels display editing + +/** + * @defgroup mainapi Functions comprising the main panels API + * @{ + */ + +/** + * Main API entry point to edit a panel display. + * + * Sample implementations utiltizing the the complex $destination behavior can be found + * in panels_page_edit_content() and, in a separate contrib module, OG Blueprints + * (http://drupal.org/project/og_blueprints), og_blueprints_blueprint_edit(). + * + * @ingroup mainapi + * + * @param object $display instanceof panels_display \n + * A fully loaded panels $display object, as returned from panels_load_display(). + * Merely passing a did is NOT sufficient. \n + * Note that 'fully loaded' means the $display must already be loaded with any contexts + * the caller wishes to have set for the display. + * @param mixed $destination \n + * The redirect destination that the user should be taken to on form submission or + * cancellation. With panels_edit, $destination has complex effects on the return + * values of panels_edit() once the form has been submitted. See the explanation of + * the return value below to understand the different types of values returned by panels_edit() + * at different stages of FAPI. Under most circumstances, simply passing in + * drupal_get_destination() is all that's necessary. + * @param array $content_types \n + * An associative array of allowed content types, typically as returned from + * panels_common_get_allowed_types(). Note that context partially governs available content types, + * so you will want to create any relevant contexts using panels_create_context() or + * panels_create_context_empty() to make sure all the appropriate content types are available. + * + * @return + * Because the functions called by panels_edit() invoke the form API, this function + * returns different values depending on the stage of form submission we're at. In Drupal 5, + * the phase of form submission is indicated by the contents of $_POST['op']. Here's what you'll + * get at different stages: + * -# If !$_POST['op']: then we're on on the initial passthrough and the form is being + * rendered, so it's the $form itself that's being returned. Because negative margins, + * a common CSS technique, bork the display editor's ajax drag-and-drop, it's important + * that the $output be printed, not returned. Use this syntax in the caller function: \n + * print theme('page', panels_edit($display, $destination, $content_types), FALSE); \n + * -# If $_POST['op'] == t('Cancel'): form submission has been cancelled. If empty($destination) == FALSE, + * then there is no return value and the panels API takes care of redirecting to $destination. + * If empty($destination) == TRUE, then there's still no return value, but the caller function + * has to take care of form redirection. + * -# If $_POST['op'] == ('Save'): the form has been submitted successfully and has run through + * panels_edit_display_submit(). $output depends on the value of $destination: + * - If empty($destination) == TRUE: $output contains the modified $display + * object, and no redirection will occur. This option is useful if the caller + * needs to perform additional operations on or with the modified $display before + * the page request is complete. Using hook_form_alter() to add an additional submit + * handler is typically the preferred method for something like this, but there + * are certain use cases where that is infeasible and $destination = NULL should + * be used instead. If this method is employed, the caller will need to handle form + * redirection. Note that having $_REQUEST['destination'] set, whether via + * drupal_get_destination() or some other method, will NOT interfere with this + * functionality; consequently, you can use drupal_get_destination() to safely store + * your desired redirect in the caller function, then simply use drupal_goto() once + * panels_edit() has done its business. + * - If empty($destination) == FALSE: the form will redirect to the URL string + * given in $destination and NO value will be returned. + */ +function panels_edit($display, $destination = NULL, $content_types = NULL, $title = FALSE) { + ctools_include('display-edit', 'panels'); + ctools_include('ajax'); + ctools_include('plugins', 'panels'); + return _panels_edit($display, $destination, $content_types, $title); +} + +/** + * API entry point for selecting a layout for a given display. + * + * Layout selection is nothing more than a list of radio items encompassing the available + * layouts for this display, as defined by .inc files in the panels/layouts subdirectory. + * The only real complexity occurs when a user attempts to change the layout of a display + * that has some content in it. + * + * @param object $display instanceof panels_display \n + * A fully loaded panels $display object, as returned from panels_load_display(). + * Merely passing a did is NOT sufficient. + * @param string $finish + * A string that will be used for the text of the form submission button. If no value is provided, + * then the form submission button will default to t('Save'). + * @param mixed $destination + * Basic usage is a string containing the URL that the form should redirect to upon submission. + * For a discussion of advanced usages, see panels_edit(). + * @param mixed $allowed_layouts + * Allowed layouts has three different behaviors that depend on which of three value types + * are passed in by the caller: + * #- if $allowed_layouts instanceof panels_allowed_layouts (includes subclasses): the most + * complex use of the API. The caller is passing in a loaded panels_allowed_layouts object + * that the client module previously created and stored somewhere using a custom storage + * mechanism. + * #- if is_string($allowed_layouts): the string will be used in a call to variable_get() which + * will call the $allowed_layouts . '_allowed_layouts' var. If the data was stored properly + * in the system var, the $allowed_layouts object will be unserialized and recreated. + * @see panels_common_set_allowed_layouts() + * #- if is_null($allowed_layouts): the default behavior, which also provides backwards + * compatibility for implementations of the Panels2 API written before beta4. In this case, + * a dummy panels_allowed_layouts object is created which does not restrict any layouts. + * Subsequent behavior is indistinguishable from pre-beta4 behavior. + * + * @return + * Can return nothing, or a modified $display object, or a redirection string; return values for the + * panels_edit* family of functions are quite complex. See panels_edit() for detailed discussion. + * @see panels_edit() + */ +function panels_edit_layout($display, $finish, $destination = NULL, $allowed_layouts = NULL) { + ctools_include('display-layout', 'panels'); + ctools_include('plugins', 'panels'); + return _panels_edit_layout($display, $finish, $destination, $allowed_layouts); +} + +// --------------------------------------------------------------------------- +// Panels database functions + +/** + * Forms the basis of a panel display + * + */ +class panels_display { + var $args = array(); + var $content = array(); + var $panels = array(); + var $incoming_content = NULL; + var $css_id = NULL; + var $context = array(); + var $did = 'new'; + var $renderer; + + function panels_display() { + // Set the default renderer to either the legacy or the standard renderer, + // depending on the legacy rendering state + $this->renderer = variable_get('panels_legacy_rendering_mode', TRUE) ? 'legacy' : 'standard'; + } + + function add_pane(&$pane, $location = NULL) { + // If no location specified, use what's set in the pane. + if (empty($location)) { + $location = $pane->panel; + } + else { + $pane->panel = $location; + } + + // Get a temporary pid for this pane. + $pane->pid = "new-" . $this->next_new_pid(); + + // Add the pane to the approprate spots. + $this->content[$pane->pid] = &$pane; + $this->panels[$location][] = $pane->pid; + } + + function duplicate_pane($pid, $location = FALSE) { + $pane = $this->clone_pane($pid); + $this->add_pane($pane, $location); + } + + function clone_pane($pid) { + $pane = drupal_clone($this->content[$pid]); + return $pane; + } + + function next_new_pid() { + // We don't use static vars to record the next new pid because + // temporary pids can last for years in exports and in caching + // during editing. + $id = array(0); + foreach (array_keys($this->content) as $pid) { + if (!is_numeric($pid)) { + $id[] = substr($pid, 4); + } + } + $next_id = max($id); + return ++$next_id; + } + + /** + * Get the title from a display. + * + * The display must have already been rendered, or the setting to set the + * display's title from a pane's title will not have worked. + * + * @return + * The title to use. If NULL, this means to let any default title that may be in use + * pass through. i.e, do not actually set the title. + */ + function get_title() { + switch ($this->hide_title) { + case PANELS_TITLE_NONE: + return ''; + + case PANELS_TITLE_PANE: + return isset($this->stored_pane_title) ? $this->stored_pane_title : ''; + + case PANELS_TITLE_FIXED: + case FALSE; // For old exported panels that are not in the database. + if (!empty($this->title)) { + return filter_xss_admin(ctools_context_keyword_substitute($this->title, array(), $this->context)); + } + return NULL; + } + } + + /** + * Render this panels display. + * + * After checking to ensure the designated layout plugin is valid, a + * display renderer object is spawned and runs its rendering logic. + * + * @param mixed $renderer + * An instantiated display renderer object, or the name of a display + * renderer plugin+class to be fetched. Defaults to NULL. When NULL, the + * predesignated display renderer will be used. + */ + function render($renderer = NULL) { + $layout = panels_get_layout($this->layout); + if (!$layout) { + return NULL; + } + + // If we were not given a renderer object, load it. + if (!is_object($renderer)) { + // If the renderer was not specified, default to $this->renderer + // which is either standard or was already set for us. + $renderer = panels_get_renderer_handler(!empty($renderer) ? $renderer : $this->renderer, $this); + if (!$renderer) { + return NULL; + } + } + + $output = ''; + // Let modules act just prior to render. + foreach (module_implements('panels_pre_render') as $module) { + $function = $module . '_panels_pre_render'; + $output .= $function($this, $renderer); + } + + $output .= $renderer->render(); + + // Let modules act just after render. + foreach (module_implements('panels_post_render') as $module) { + $function = $module . '_panels_post_render'; + $output .= $function($this, $renderer); + } + return $output; + } +} + +/** + * }@ End of 'defgroup mainapi', although other functions are specifically added later + */ + +/** + * Creates a new display, setting the ID to our magic new id. + */ +function panels_new_display() { + ctools_include('export'); + $display = ctools_export_new_object('panels_display', FALSE); + $display->did = 'new'; + return $display; +} + +/** + * Create a new pane. + * + * @todo -- use schema API for some of this? + */ +function panels_new_pane($type, $subtype, $set_defaults = FALSE) { + ctools_include('export'); + $pane = ctools_export_new_object('panels_pane', FALSE); + $pane->pid = 'new'; + $pane->type = $type; + $pane->subtype = $subtype; + if ($set_defaults) { + $content_type = ctools_get_content_type($type); + $content_subtype = ctools_content_get_subtype($content_type, $subtype); + $pane->configuration = ctools_content_get_defaults($content_type, $content_subtype); + } + + return $pane; +} + +/** + * Load and fill the requested $display object(s). + * + * Helper function primarily for for panels_load_display(). + * + * @param array $dids + * An indexed array of dids to be loaded from the database. + * + * @return $displays + * An array of displays, keyed by their display dids. + * + * @todo schema API can drasticly simplify this code. + */ +function panels_load_displays($dids) { + $displays = array(); + if (empty($dids) || !is_array($dids)) { + return $displays; + } + + $result = db_query("SELECT * FROM {panels_display} WHERE did IN (" . db_placeholders($dids) . ")", $dids); + + ctools_include('export'); + while ($obj = db_fetch_object($result)) { + $displays[$obj->did] = ctools_export_unpack_object('panels_display', $obj); + // Modify the hide_title field to go from a bool to an int if necessary. + } + + $result = db_query("SELECT * FROM {panels_pane} WHERE did IN (" . db_placeholders($dids) . ") ORDER BY did, panel, position", $dids); + + while ($obj = db_fetch_object($result)) { + $pane = ctools_export_unpack_object('panels_pane', $obj); + + $displays[$pane->did]->panels[$pane->panel][] = $pane->pid; + $displays[$pane->did]->content[$pane->pid] = $pane; + } + + return $displays; +} + +/** + * Load a single display. + * + * @ingroup mainapi + * + * @param int $did + * The display id (did) of the display to be loaded. + * + * @return object $display instanceof panels_display \n + * Returns a partially-loaded panels_display object. $display objects returned from + * from this function have only the following data: + * - $display->did (the display id) + * - $display->name (the 'name' of the display, where applicable - it often isn't) + * - $display->layout (a string with the system name of the display's layout) + * - $display->panel_settings (custom layout style settings contained in an associative array; NULL if none) + * - $display->layout_settings (panel size and configuration settings for Flexible layouts; NULL if none) + * - $display->css_id (the special css_id that has been assigned to this display, if any; NULL if none) + * - $display->content (an array of pane objects, keyed by pane id (pid)) + * - $display->panels (an associative array of panel regions, each an indexed array of pids in the order they appear in that region) + * - $display->cache (any relevant data from panels_simple_cache) + * - $display->args + * - $display->incoming_content + * + * While all of these members are defined, $display->context is NEVER defined in the returned $display; + * it must be set using one of the ctools_context_create() functions. + */ +function panels_load_display($did) { + $displays = panels_load_displays(array($did)); + if (!empty($displays)) { + return array_shift($displays); + } +} + +/** + * Save a display object. + * + * @ingroup mainapi + * + * Note a new $display only receives a real did once it is run through this function. + * Until then, it uses a string placeholder, 'new', in place of a real did. The same + * applies to all new panes (whether on a new $display or not); in addition, + * panes have sequential numbers appended, of the form 'new-1', 'new-2', etc. + * + * @param object $display instanceof panels_display \n + * The display object to be saved. Passed by reference so the caller need not use + * the return value for any reason except convenience. + * + * @return object $display instanceof panels_display \n + */ +function panels_save_display(&$display) { + $update = (isset($display->did) && is_numeric($display->did)) ? array('did') : array(); + drupal_write_record('panels_display', $display, $update); + + $pids = array(); + if ($update) { + // Get a list of all panes currently in the database for this display so we can know if there + // are panes that need to be deleted. (i.e, aren't currently in our list of panes). + $result = db_query("SELECT pid FROM {panels_pane} WHERE did = %d", $display->did); + while ($pane = db_fetch_object($result)) { + $pids[$pane->pid] = $pane->pid; + } + } + + // update all the panes + ctools_include('plugins', 'panels'); + ctools_include('content'); + + foreach ($display->panels as $id => $panes) { + $position = 0; + $new_panes = array(); + foreach ((array) $panes as $pid) { + if (!isset($display->content[$pid])) { + continue; + } + $pane = $display->content[$pid]; + $type = ctools_get_content_type($pane->type); + + $pane->position = $position++; + $pane->did = $display->did; + + $old_pid = $pane->pid; + drupal_write_record('panels_pane', $pane, is_numeric($pid) ? array('pid') : array()); + + if ($pane->pid != $old_pid) { + // and put it back so our pids and positions can be used + unset($display->content[$id]); + $display->content[$pane->pid] = $pane; + + // If the title pane was one of our panes that just got its ID changed, + // we need to change it in the database, too. + if (isset($display->title_pane) && $display->title_pane == $old_pid) { + $display->title_pane = $pane->pid; + // Do a simple update query to write it so we don't have to rewrite + // the whole record. We can't just save writing the whole record here + // because it was needed to get the did. Chicken, egg, more chicken. + db_query("UPDATE {panels_display} SET title_pane = %d WHERE did = %d", $pane->pid, $display->did); + } + } + + // re-add this to the list of content for this panel. + $new_panes[] = $pane->pid; + + // Remove this from the list of panes scheduled for deletion. + if (isset($pids[$pane->pid])) { + unset($pids[$pane->pid]); + } + } + + $display->panels[$id] = $new_panes; + } + if (!empty($pids)) { + db_query("DELETE FROM {panels_pane} WHERE pid IN (" . db_placeholders($pids) . ")", $pids); + } + + // Clear any cached content for this display. + panels_clear_cached_content($display); + + // Allow other modules to take action when a display is saved. + module_invoke_all('panels_display_save', $display); + + // Log the change to watchdog, using the same style as node.module + $watchdog_args = array('%did' => $display->did); + if (!empty($display->title)) { + $watchdog_args['%title'] = $display->title; + watchdog('content', 'Panels: saved display "%title" with display id %did', $watchdog_args, WATCHDOG_NOTICE); + } + else { + watchdog('content', 'Panels: saved display with id %did', $watchdog_args, WATCHDOG_NOTICE); + } + + // to be nice, even tho we have a reference. + return $display; +} + +/** + * Delete a display. + */ +function panels_delete_display($display) { + if (is_object($display)) { + $did = $display->did; + } + else { + $did = $display; + } + db_query("DELETE FROM {panels_display} WHERE did = %d", $did); + db_query("DELETE FROM {panels_pane} WHERE did = %d", $did); +} + +/** + * Exports the provided display into portable code. + * + * This function is primarily intended as a mechanism for cloning displays. + * It generates an exact replica (in code) of the provided $display, with + * the exception that it replaces all ids (dids and pids) with 'new-*' values. + * Only once panels_save_display() is called on the code version of $display will + * the exported display written to the database and permanently saved. + * + * @see panels_page_export() or _panels_page_fetch_display() for sample implementations. + * + * @ingroup mainapi + * + * @param object $display instanceof panels_display \n + * This export function does no loading of additional data about the provided + * display. Consequently, the caller should make sure that all the desired data + * has been loaded into the $display before calling this function. + * @param string $prefix + * A string prefix that is prepended to each line of exported code. This is primarily + * used for prepending a double space when exporting so that the code indents and lines up nicely. + * + * @return string $output + * The passed-in $display expressed as code, ready to be imported. Import by running + * eval($output) in the caller function; doing so will create a new $display variable + * with all the exported values. Note that if you have already defined a $display variable in + * the same scope as where you eval(), your existing $display variable WILL be overwritten. + */ +function panels_export_display($display, $prefix = '') { + ctools_include('export'); + $output = ctools_export_object('panels_display', $display, $prefix); + + // Initialize empty properties. + $output .= $prefix . '$display->content = array()' . ";\n"; + $output .= $prefix . '$display->panels = array()' . ";\n"; + $panels = array(); + + $title_pid = 0; + if (!empty($display->content)) { + $pid_counter = 0; + $region_counters = array(); + foreach ($display->content as $pane) { + $pid = 'new-' . ++$pid_counter; + if ($pane->pid == $display->title_pane) { + $title_pid = $pid; + } + $pane->pid = $pid; + $output .= ctools_export_object('panels_pane', $pane, $prefix . ' '); + $output .= "$prefix " . '$display->content[\'' . $pane->pid . '\'] = $pane' . ";\n"; + if (!isset($region_counters[$pane->panel])) { + $region_counters[$pane->panel] = 0; + } + $output .= "$prefix " . '$display->panels[\'' . $pane->panel . '\'][' . $region_counters[$pane->panel]++ .'] = \'' . $pane->pid . "';\n"; + } + } + $output .= $prefix . '$display->hide_title = '; + switch ($display->hide_title) { + case PANELS_TITLE_FIXED: + $output .= 'PANELS_TITLE_FIXED'; + break; + case PANELS_TITLE_NONE: + $output .= 'PANELS_TITLE_NONE'; + break; + case PANELS_TITLE_PANE: + $output .= 'PANELS_TITLE_PANE'; + break; + } + $output .= ";\n"; + + $output .= $prefix . '$display->title_pane =' . " '$title_pid';\n"; + return $output; +} + +/** + * Render a display by loading the content into an appropriate + * array and then passing through to panels_render_layout. + * + * if $incoming_content is NULL, default content will be applied. Use + * an empty string to indicate no content. + * @ingroup hook_invocations + */ +function panels_render_display(&$display, $renderer = NULL) { + ctools_include('display-render', 'panels'); + ctools_include('plugins', 'panels'); + ctools_include('context'); + + if (!empty($display->context)) { + if ($form_context = ctools_context_get_form($display->context)) { + $form_context->form['#theme'] = 'panels_render_display_form'; + $form_context->form['#display'] = &$display; + $form_context->form['#form_context_id'] = $form_context->id; + return drupal_render_form($form_context->form_id, $form_context->form); + } + } + return $display->render($renderer); +} + +/** + * Theme function to render our panel as a form. + * + * When rendering a display as a form, the entire display needs to be + * inside the <form> tag so that the form can be spread across the + * panes. This sets up the form system to be the main caller and we + * then operate as a theme function of the form. + */ +function theme_panels_render_display_form($form) { + $form['#children'] = $form['#display']->render(); + drupal_render($form); + return theme('form', $form); +} + +// @layout +function panels_print_layout_icon($id, $layout, $title = NULL) { + ctools_add_css('panels_admin', 'panels'); + $file = $layout['path'] . '/' . $layout['icon']; + return theme('panels_layout_icon', $id, theme('image', $file, strip_tags($layout['title']), strip_tags($layout['description'])), $title); +} + +/** + * Theme the layout icon image + * @layout + * @todo move to theme.inc + */ +function theme_panels_layout_icon($id, $image, $title = NULL) { + $output = '<div class="layout-icon">'; + $output .= $image; + if ($title) { + $output .= '<div class="caption">' . $title . '</div>'; + } + $output .= '</div>'; + return $output; +} + +/** + * Theme the layout link image + * @layout + */ +function theme_panels_layout_link($title, $id, $image, $link) { + $output = '<div class="layout-link">'; + $output .= $image; + $output .= '<div>' . $title . '</div>'; + $output .= '</div>'; + return $output; +} + +/** + * Print the layout link. Sends out to a theme function. + * @layout + */ +function panels_print_layout_link($id, $layout, $link, $options = array()) { + if (isset($options['query']['q'])) { + unset($options['query']['q']); + } + + ctools_add_css('panels_admin', 'panels'); + $file = $layout['path'] . '/' . $layout['icon']; + $image = l(theme('image', $file), $link, array('html' => true) + $options); + $title = l($layout['title'], $link, $options); + return theme('panels_layout_link', $title, $id, $image, $link); +} + + +/** + * Gateway to the PanelsLegacyState class/object, which does all legacy state + * checks and provides information about the cause of legacy states as needed. + * + * @return PanelsLegacyState $legacy + */ +function panels_get_legacy_state() { + static $legacy = NULL; + if (!isset($legacy)) { + ctools_include('legacy', 'panels'); + $legacy = new PanelsLegacyState(); + } + return $legacy; +} + +/** + * Get the display that is currently being rendered as a page. + * + * Unlike in previous versions of this, this only returns the display, + * not the page itself, because there are a number of different ways + * to get to this point. It is hoped that the page data isn't needed + * at this point. If it turns out there is, we will do something else to + * get that functionality. + */ +function panels_get_current_page_display($change = NULL) { + static $display = NULL; + if ($change) { + $display = $change; + } + + return $display; +} + +/** + * Clean up the panel pane variables for the template. + */ +function template_preprocess_panels_pane($vars) { + $content = $vars['output']; + // basic classes + $vars['classes'] = 'panel-pane'; + $vars['id'] = ''; + + // Add some usable classes based on type/subtype + ctools_include('cleanstring'); + $type_class = $content->type ? 'pane-'. ctools_cleanstring($content->type, array('lower case' => TRUE)) : ''; + $subtype_class = $content->subtype ? 'pane-'. ctools_cleanstring($content->subtype, array('lower case' => TRUE)) : ''; + + // Sometimes type and subtype are the same. Avoid redudant classes. + if ($type_class != $subtype_class) { + $vars['classes'] .= " $type_class $subtype_class"; + } + else { + $vars['classes'] .= " $type_class"; + } + + // Add id and custom class if sent in. + if (!empty($content->content)) { + if (!empty($content->css_id)) { + $vars['id'] = ' id="' . $content->css_id . '"'; + } + if (!empty($content->css_class)) { + $vars['classes'] .= ' ' . $content->css_class; + } + } + + // administrative links, only if there is permission. + $vars['admin_links'] = ''; + if (user_access('view pane admin links') && !empty($content->admin_links)) { + $vars['admin_links'] = theme('links', $content->admin_links); + } + + $vars['title'] = !empty($content->title) ? $content->title : ''; + + $vars['feeds'] = !empty($content->feeds) ? implode(' ', $content->feeds) : ''; + $vars['content'] = !empty($content->content) ? $content->content : ''; + + $vars['links'] = !empty($content->links) ? theme('links', $content->links) : ''; + $vars['more'] = ''; + if (!empty($content->more)) { + if (empty($content->more['title'])) { + $content->more['title'] = t('more'); + } + $vars['more'] = l($content->more['title'], $content->more['href'], $content->more); + } +} + +/** + * Route Panels' AJAX calls to the correct object. + * + * Panels' AJAX is controlled mostly by renderer objects. This menu callback + * accepts the incoming request, figures out which object should handle the + * request, and attempts to route it. If no object can be found, the default + * Panels editor object is used. + * + * Calls are routed via the ajax_* method space. For example, if visiting + * panels/ajax/add-pane then $renderer::ajax_add_pane() will be called. + * This means commands can be added without having to create new callbacks. + * + * The first argument *must always* be the cache key so that a cache object + * can be passed through. Other arguments will be passed through untouched + * so that the method can do whatever it needs to do. + */ +function panels_ajax_router() { + $args = func_get_args(); + if (count($args) < 3) { + return MENU_NOT_FOUND; + } + + ctools_include('display-edit', 'panels'); + ctools_include('plugins', 'panels'); + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + ctools_include('content'); + + $plugin_name = array_shift($args); + $method = array_shift($args); + $cache_key = array_shift($args); + + $plugin = panels_get_display_renderer($plugin_name); + if (!$plugin) { + // This is the default renderer for handling AJAX commands. + $plugin = panels_get_display_renderer('editor'); + } + + $cache = panels_edit_cache_get($cache_key); + if (empty($cache)) { + return MENU_ACCESS_DENIED; + } + + $renderer = panels_get_renderer_handler($plugin, $cache->display); + if (!$renderer) { + return MENU_ACCESS_DENIED; + } + + $method = 'ajax_' . str_replace('-', '_', $method); + if (!method_exists($renderer, $method)) { + return MENU_NOT_FOUND; + } + + $renderer->cache = &$cache; + ctools_include('cleanstring'); + $renderer->clean_key = ctools_cleanstring($cache_key); + + $output = call_user_func_array(array($renderer, $method), $args); + if (empty($output) && !empty($renderer->commands)) { + return ctools_ajax_render($renderer->commands); + } + return $output; +} + +// -------------------------------------------------------------------------- +// Panels caching functions and callbacks +// +// When editing displays and the like, Panels has a caching system that relies +// on a callback to determine where to get the actual cache. + +// @todo This system needs to be better documented so that it can be +// better used. + +/** + * Get an object from cache. + */ +function panels_cache_get($obj, $did, $skip_cache = FALSE) { + ctools_include('object-cache'); + // we often store contexts in cache, so let's just make sure we can load + // them. + ctools_include('context'); + return ctools_object_cache_get($obj, 'panels_display:' . $did, $skip_cache); +} + +/** + * Save the edited object into the cache. + */ +function panels_cache_set($obj, $did, $cache) { + ctools_include('object-cache'); + return ctools_object_cache_set($obj, 'panels_display:' . $did, $cache); +} + +/** + * Clear a object from the cache; used if the editing is aborted. + */ +function panels_cache_clear($obj, $did) { + ctools_include('object-cache'); + return ctools_object_cache_clear($obj, 'panels_display:' . $did); +} + +/** + * Create the default cache for editing panel displays. + * + * If an application is using the Panels display editor without having + * specified a cache key, this method can be used to create the default + * cache. + */ +function panels_edit_cache_get_default(&$display, $content_types = NULL, $title = FALSE) { + if (empty($content_types)) { + $content_types = ctools_content_get_available_types(); + } + + $display->cache_key = $display->did; + panels_cache_clear('display', $display->did); + + $cache = new stdClass(); + $cache->display = &$display; + $cache->content_types = $content_types; + $cache->display_title = $title; + + panels_edit_cache_set($cache); + return $cache; +} + +/** + * Method to allow modules to provide their own caching mechanism for the + * display editor. + */ +function panels_edit_cache_get($cache_key) { + if (strpos($cache_key, ':') !== FALSE) { + list($module, $argument) = explode(':', $cache_key, 2); + return module_invoke($module, 'panels_cache_get', $argument); + } + + // Fall back to our normal method: + return panels_cache_get('display', $cache_key); +} + +/** + * Method to allow modules to provide their own caching mechanism for the + * display editor. + */ +function panels_edit_cache_set($cache) { + $cache_key = $cache->display->cache_key; + if (strpos($cache_key, ':') !== FALSE) { + list($module, $argument) = explode(':', $cache_key, 2); + return module_invoke($module, 'panels_cache_set', $argument, $cache); + } + + // Fall back to our normal method: + return panels_cache_set('display', $cache_key, $cache); +} + +/** + * Method to allow modules to provide their own mechanism to write the + * cache used in the display editor. + */ +function panels_edit_cache_save($cache) { + $cache_key = $cache->display->cache_key; + if (strpos($cache_key, ':') !== FALSE) { + list($module, $argument) = explode(':', $cache_key, 2); + if (function_exists($module . '_panels_cache_save')) { + return module_invoke($module, 'panels_cache_save', $argument, $cache); + } + } + + // Fall back to our normal method: + return panels_save_display($cache->display); +} + +/** + * Method to allow modules to provide their own mechanism to clear the + * cache used in the display editor. + */ +function panels_edit_cache_clear($cache) { + $cache_key = $cache->display->cache_key; + if (strpos($cache_key, ':') !== FALSE) { + list($module, $argument) = explode(':', $cache_key, 2); + if (function_exists($module . '_panels_cache_clear')) { + return module_invoke($module, 'panels_cache_clear', $argument, $cache); + } + } + + // Fall back to our normal method: + return panels_cache_clear('display', $cache_key); +} + +/** + * Method to allow modules to provide a mechanism to break locks. + */ +function panels_edit_cache_break_lock($cache) { + if (empty($cache->locked)) { + return; + } + + $cache_key = $cache->display->cache_key; + if (strpos($cache_key, ':') !== FALSE) { + list($module, $argument) = explode(':', $cache_key, 2); + if (function_exists($module . '_panels_cache_break_lock')) { + return module_invoke($module, 'panels_cache_break_lock', $argument, $cache); + } + } + + // Normal panel display editing has no locks, so we do nothing if there is + // no fallback. + return; +} + +// -------------------------------------------------------------------------- +// Callbacks on behalf of the panel_context plugin. +// +// The panel_context plugin lets Panels be used in page manager. These +// callbacks allow the display editing system to use the page manager +// cache rather than the default display cache. They are routed by the cache +// key via panels_edit_cache_* functions. + +/** + * Get display edit cache on behalf of panel context. + * + * The key is the second half of the key in this form: + * panel_context:TASK_NAME:HANDLER_NAME; + */ +function panel_context_panels_cache_get($key) { + ctools_include('common', 'panels'); + ctools_include('context'); + ctools_include('context-task-handler'); + // this loads the panel context inc even if we don't use the plugin. + $plugin = page_manager_get_task_handler('panel_context'); + + list($task_name, $handler_name) = explode(':', $key, 2); + $page = page_manager_get_page_cache($task_name); + if (isset($page->display_cache[$handler_name])) { + return $page->display_cache[$handler_name]; + } + + if ($handler_name) { + $handler = &$page->handlers[$handler_name]; + } + else { + $handler = &$page->new_handler; + } + $cache = new stdClass(); + + $cache->display = &panels_panel_context_get_display($handler); + $cache->display->context = ctools_context_handler_get_all_contexts($page->task, $page->subtask, $handler); + $cache->display->cache_key = 'panel_context:' . $key; + $cache->content_types = panels_common_get_allowed_types('panels_page', $cache->display->context); + $cache->display_title = TRUE; + $cache->locked = $page->locked; + + return $cache; +} + +/** + * Get the Page Manager cache for the panel_context plugin. + */ +function _panel_context_panels_cache_get_page_cache($key, $cache) { + list($task_name, $handler_name) = explode(':', $key, 2); + $page = page_manager_get_page_cache($task_name); + $page->display_cache[$handler_name] = $cache; + if ($handler_name) { + $page->handlers[$handler_name]->conf['display'] = $cache->display; + $page->handler_info[$handler_name]['changed'] |= PAGE_MANAGER_CHANGED_CACHED; + } + else { + $page->new_handler->conf['display'] = $cache->display; + } + + return $page; +} + +/** + * Store a display edit in progress in the page cache. + */ +function panel_context_panels_cache_set($key, $cache) { + $page = _panel_context_panels_cache_get_page_cache($key, $cache); + page_manager_set_page_cache($page); +} + +/** + * Save all changes made to a display using the Page Manager page cache. + */ +function panel_context_panels_cache_clear($key, $cache) { + $page = _panel_context_panels_cache_get_page_cache($key, $cache); + page_manager_clear_page_cache($page->task_name); +} + +/** + * Save all changes made to a display using the Page Manager page cache. + */ +function panel_context_panels_cache_save($key, $cache) { + $page = _panel_context_panels_cache_get_page_cache($key, $cache); + page_manager_save_page_cache($page); +} + +/** + * Break the lock on a page manager page. + */ +function panel_context_panels_cache_break_lock($key, $cache) { + $page = _panel_context_panels_cache_get_page_cache($key, $cache); + ctools_object_cache_clear_all('page_manager_page', $page->task_name); +} + +// -------------------------------------------------------------------------- +// Callbacks on behalf of the panels page wizards +// +// The page wizards are a pluggable set of 'wizards' to make it easy to create +// specific types of pages based upon whatever someone felt like putting +// together. Since they will very often have content editing, we provide +// a generic mechanism to allow them to store their editing cache in the +// wizard cache. +// +// For them to use this mechanism, they just need to use: +// $cache = panels_edit_cache_get('panels_page_wizard:' . $plugin['name']); + +/** + * Get display edit cache for the panels mini export UI + * + * The key is the second half of the key in this form: + * panels_page_wizard:TASK_NAME:HANDLER_NAME; + */ +function panels_page_wizard_panels_cache_get($key) { + ctools_include('page-wizard'); + ctools_include('context'); + $wizard_cache = page_manager_get_wizard_cache($key); + if (isset($wizard_cache->display_cache)) { + return $wizard_cache->display_cache; + } + + ctools_include('common', 'panels'); + $cache = new stdClass(); + $cache->display = $wizard_cache->display; + $cache->display->context = !empty($wizard_cache->context) ? $wizard_cache->context : array(); + $cache->display->cache_key = 'panels_page_wizard:' . $key; + $cache->content_types = panels_common_get_allowed_types('panels_page', $cache->display->context); + $cache->display_title = TRUE; + + return $cache; +} + +/** + * Store a display edit in progress in the page cache. + */ +function panels_page_wizard_panels_cache_set($key, $cache) { + ctools_include('page-wizard'); + $wizard_cache = page_manager_get_wizard_cache($key); + $wizard_cache->display_cache = $cache; + page_manager_set_wizard_cache($wizard_cache); +} + +// -------------------------------------------------------------------------- +// General utility functions + +/** + * Perform a drupal_goto on a destination that may be an array like url(). + */ +function panels_goto($destination) { + if (!is_array($destination)) { + return drupal_goto($destination); + } + else { + // Prevent notices by adding defaults + $destination += array( + 'query' => NULL, + 'fragment' => NULL, + 'http_response_code' => NULL, + ); + + return drupal_goto($destination['path'], $destination['query'], $destination['fragment'], $destination['http_response_code']); + } +} + + +/** + * For external use: Given a layout ID and a $content array, return the + * panel display. + * + * The content array is filled in based upon the content available in the + * layout. If it's a two column with a content array defined like + * @code + * array( + * 'left' => t('Left side'), + * 'right' => t('Right side') + * ), + * @endcode + * + * Then the $content array should be + * @code + * array( + * 'left' => $output_left, + * 'right' => $output_right, + * ) + * @endcode + * + * The output within each panel region can be either a single rendered + * HTML string or an array of rendered HTML strings as though they were + * panes. They will simply be concatenated together without separators. + */ +function panels_print_layout($layout, $content, $meta = 'standard') { + ctools_include('plugins', 'panels'); + + // Create a temporary display for this. + $display = panels_new_display(); + $display->layout = is_array($layout) ? $layout['name'] : $layout; + $display->content = $content; + + // Get our simple renderer + $renderer = panels_get_renderer_handler('simple', $display); + $renderer->meta_location = $meta; + + return $renderer->render(); +} + +// -------------------------------------------------------------------------- +// Deprecated functions +// +// Everything below this line will eventually go away. + +/** + * Load a panels include file. + * + * @deprecated This function is deprecated and should no longer be used. It will + * be removed in the next major version of Panels. Use ctools_include() instead. + */ +function panels_load_include($include, $path = 'includes/') { + static $loaded = array(); + if (empty($loaded["$path$include.inc"])) { + require_once './' . panels_get_path("$path$include.inc"); + $loaded["$path$include.inc"] = TRUE; + } +} + +/** + * panels path helper function + */ +function panels_get_path($file, $base_path = FALSE, $module = 'panels') { + $output = $base_path ? base_path() : ''; + return $output . drupal_get_path('module', $module) . '/' . $file; +} + +/** + * Given a full layout structure and a content array, render a panel display. + * + * @deprecated This function represents an old approach to rendering, and is + * retained only as a temporary support for other modules still using that + * approach. It will be removed in the next major version of Panels. + */ +function panels_render_layout($layout, $content, $css_id = NULL, $settings = array(), $display = NULL) { + if (!empty($layout['css'])) { + if (file_exists(path_to_theme() . '/' . $layout['css'])) { + drupal_add_css(path_to_theme() . '/' . $layout['css']); + } + else { + drupal_add_css($layout['path'] . '/' . $layout['css']); + } + } + // This now comes after the CSS is added, because panels-within-panels must + // have their CSS added in the right order; inner content before outer content. + + // If $content is an object, it's a $display and we have to render its panes. + if (is_object($content)) { + $display = $content; + if (empty($display->cache['method'])) { + $content = panels_render_panes($display); + } + else { + $cache = panels_get_cached_content($display, $display->args, $display->context); + if ($cache === FALSE) { + $cache = new panels_cache_object(); + $cache->set_content(panels_render_panes($display)); + panels_set_cached_content($cache, $display, $display->args, $display->context); + } + $content = $cache->content; + } + } + + $output = theme($layout['theme'], check_plain($css_id), $content, $settings, $display); + + return $output; +} + +/** + * Get a list of panel regions available in the layout. + * + * @deprecated Use panels_get_regions instead. + */ +function panels_get_panels($layout, $display) { + return panels_get_regions($layout, $display); +} + +/** + * Select a context for a pane. + * + * @param $pane + * A fully populated pane. + * @param $contexts + * A keyed array of available contexts. + * + * @return + * The matching contexts or NULL if none or necessary, or FALSE if + * requirements can't be met. + * + * @deprecated this function will be removed. + */ +function panels_pane_select_context($pane, $contexts) { + return ctools_content_select_context($pane->type, $pane->subtype, $pane->configuration, $contexts); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_export/panels_export.module b/drupal/sites/default/boinc/modules/contrib/panels/panels_export/panels_export.module new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/css/panels_ipe.css b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/css/panels_ipe.css new file mode 100644 index 0000000000000000000000000000000000000000..77edc1589607cfa8171cdd65147f52f9ee39392c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/css/panels_ipe.css @@ -0,0 +1,209 @@ +div.panels-ipe-handlebar-wrapper { + border-bottom: #898AAB solid 2px; +} + +.panels-ipe-editing div.panels-ipe-portlet-wrapper { + margin-top: 1em; + border: #898AAB solid 2px; + -moz-border-radius-bottomleft:8px; + -moz-border-radius-bottomright:8px; + -moz-border-radius-topleft:2px; + -moz-border-radius-topright:2px; + + -webkit-border-radius-bottomleft:8px; + -webkit-border-radius-bottomright:8px; + -webkit-border-radius-topleft:2px; + -webkit-border-radius-topright:2px; +} + +/* Hide empty panes when not editing them. */ +.panels-ipe-empty-pane { + display: none; +} + +.panels-ipe-editing .panels-ipe-empty-pane { + display: block; +} + + +.panels-ipe-editing div.panels-ipe-portlet-wrapper:hover { + border: #FF000A solid 2px; +} + +.panels-ipe-editing .panels-ipe-sort-container .ui-sortable-helper { + background: white; +} + +.panels-ipe-editing div.panel-pane div.admin-links { + display: none !important; +} + +.panels-ipe-editing .panels-ipe-sort-container .ui-sortable-placeholder { + -moz-border-radius: 0; + -webkit-border-radius: 0; + border: 1px dotted red; + background-color: white; +} + +div.panels-ipe-handlebar-wrapper ul { + float: left; + margin: 0; + padding: 0; + text-align: right; +} + +div.panels-ipe-handlebar-wrapper li { + background: none repeat scroll 0 0 transparent; + list-style: none outside none; + margin: 0; + padding: 0; + float: left; + font: 12px/170% Verdana,sans-serif !important; +} + +div.panels-ipe-handlebar-wrapper li { + border-top: 1px solid #CCC; + border-right: 1px solid #CCC; +} + +div.panels-ipe-handlebar-wrapper li.first { + border-left: 1px solid #CCC; +} + +div.panels-ipe-draghandle { + background: #898AAB url(../images/dragger.png) top right no-repeat; + cursor: move; + height: 24px; +} + +div.panels-ipe-placeholder { + border: 1px solid black; + padding: .5em; + margin-top: .5em; + background-color: #f6f6f6; + color: black; + background-color: white; + font: 12px/170% Verdana,sans-serif !important; + text-transform: none; + letter-spacing: 0; + text-align: left; + word-spacing: 0; +} + +div.panels-ipe-placeholder h3 { + font-weight: bold; +} + +/* Hide editor-state-on elements initially */ +.panels-ipe-on { + display: none; +} + +.panels-ipe-editing .panels-ipe-on { + display: block; +} + +/* Show editor-state-off elements initially */ +.panels-ipe-off { + display: block; +} + +div.panels-ipe-handlebar-wrapper li a, +div.panels-ipe-draghandle span, +div.panels-ipe-newblock a { + background-color: #f6f6f6; + color: blue; + display: block; + padding: 0.1em 0.5em; + font: 12px/170% Verdana,sans-serif !important; + text-transform: none; + letter-spacing: 0; +} + +div.panels-ipe-newblock a { + display: inline; + border: 1px solid #CCC; + color: blue; +} + +.panels-ipe-editing .panels-ipe-portlet-content { + margin-bottom: 10px; + border: transparent dotted 1px; + overflow: hidden; +} + +.panels-ipe-editing .panels-ipe-region { + border: transparent dotted 1px; + float: left; + width: 100%; + margin-bottom: 5px; +} + +div.panels-ipe-draghandle { + border: none; +} + +.ui-sortable-placeholder { + margin: 1em; + border: 1px dotted black; + visibility: visible !important; + height: 50px !important; +} +.ui-sortable-placeholder * { + visibility: hidden; +} + +/* counteract panels_dnd.css - temporary */ +div.panels-ipe-display-container .panel-pane .pane-title { + padding: 0; +} + +/** ============================================================================ + * Controller form markup + */ + +div#panels-ipe-control-container { + z-index: 100; + position: fixed; + margin: auto; + bottom: 0; + left: 50%; + display: block; + background-color: #000; + padding: 0.5em 1em; + min-width: 9.5em; + max-width: 12.5em; + min-height: 2em; + max-height: 2.5em; + -moz-border-radius-topleft:5px; + -moz-border-radius-topright:5px; + -moz-box-shadow: #333 0px 1px 0px; + -webkit-border-radius-topleft:5px; + -webkit-border-radius-topright:5px; + -webkit-box-shadow: #333 0px 1px 0px; +} + +div.panels-ipe-pseudobutton { + cursor: pointer; + background-color: #333; + font:normal 11px/15px "Lucida Grande",Tahoma,Verdana,sans-serif; + color: #FFF; + -moz-border-radius:5px; + -moz-box-shadow: #333 0px 1px 0px; + -webkit-border-radius:5px; + -webkit-box-shadow: #333 0px 1px 0px; + padding: 0.3em 0.8em; + float: left; +} + +div.panels-ipe-control .form-submit { + float: left; + margin: 0.3em 0.5em; +} + +div.panels-ipe-form-container { + min-width: 12.5em; + min-height: 2em; + margin-left: auto; + margin-right: auto; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/images/dragger.png b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/images/dragger.png new file mode 100644 index 0000000000000000000000000000000000000000..bb3b57b2611981fb82453d1dd77ab6b34688826f Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/images/dragger.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/includes/panels_ipe.pipelines.inc b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/includes/panels_ipe.pipelines.inc new file mode 100644 index 0000000000000000000000000000000000000000..7e22852c9e3dad8442d05e5bebe99c044ea1ae28 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/includes/panels_ipe.pipelines.inc @@ -0,0 +1,44 @@ +<?php + +/** + * @file + * Bulk export of panels_layouts objects generated by Bulk export module. + */ + +/** + * Implementation of hook_default_panels_renderer_pipeline(). + */ +function panels_ipe_default_panels_renderer_pipeline() { + $pipelines = array(); + + $pipeline = new stdClass; + $pipeline->disabled = FALSE; /* Edit this to true to make a default pipeline disabled initially */ + $pipeline->api_version = 1; + $pipeline->name = 'ipe'; + $pipeline->admin_title = t('In-Place Editor'); + $pipeline->admin_description = t('Allows privileged users to update and rearrange the content while viewing this panel.'); + $pipeline->weight = 0; + $pipeline->settings = array( + 'renderers' => array( + 0 => array( + 'access' => array( + 'plugins' => array( + 0 => array( + 'name' => 'perm', + 'settings' => array( + 'perm' => 'use panels in place editing', + ), + 'context' => 'logged-in-user', + ), + ), + 'logic' => 'and', + ), + 'renderer' => 'ipe', + 'options' => array(), + ), + ), + ); + $pipelines[$pipeline->name] = $pipeline; + + return $pipelines; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/js/panels_ipe.js b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/js/panels_ipe.js new file mode 100644 index 0000000000000000000000000000000000000000..c355ad6be7a319efee56677c83e3c08daa0d8cba --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/js/panels_ipe.js @@ -0,0 +1,255 @@ + +// Ensure the $ alias is owned by jQuery. +(function($) { + +Drupal.PanelsIPE = { + editors: {}, + bindClickDelete: function(context) { + $('a.pane-delete:not(.pane-delete-processed)', context) + .addClass('pane-delete-processed') + .click(function() { + if (confirm('Remove this pane?')) { + $(this).parents('div.panels-ipe-portlet-wrapper').fadeOut('medium', function() { + $(this).empty().remove(); + }); + $(this).parents('div.panels-ipe-display-container').addClass('changed'); + } + return false; + }); + } +} + +// A ready function should be sufficient for this, at least for now +$(function() { + $.each(Drupal.settings.PanelsIPECacheKeys, function() { + Drupal.PanelsIPE.editors[this] = new DrupalPanelsIPE(this, Drupal.settings.PanelsIPESettings[this]); + }); +}); + +Drupal.behaviors.PanelsIPE = function(context) { + Drupal.PanelsIPE.bindClickDelete(context); +}; + +Drupal.CTools.AJAX.commands.initIPE = function(data) { + if (Drupal.PanelsIPE.editors[data.key]) { + Drupal.PanelsIPE.editors[data.key].initEditing(data.data); + } +}; + +Drupal.CTools.AJAX.commands.unlockIPE = function(data) { + if (confirm(data.message)) { + var ajaxOptions = { + type: "POST", + url: data.break_path, + data: { 'js': 1 }, + global: true, + success: Drupal.CTools.AJAX.respond, + error: function(xhr) { + Drupal.CTools.AJAX.handleErrors(xhr, ipe.cfg.formPath); + }, + dataType: 'json' + }; + + $.ajax(ajaxOptions); + }; +}; + +Drupal.CTools.AJAX.commands.endIPE = function(data) { + if (Drupal.PanelsIPE.editors[data.key]) { + Drupal.PanelsIPE.editors[data.key].endEditing(data); + } +}; + + + +/** + * Base object (class) definition for the Panels In-Place Editor. + * + * A new instance of this object is instanciated for every unique IPE on a given + * page. + * + * Note that this form is provisional, and we hope to replace it with a more + * flexible, loosely-coupled model that utilizes separate controllers for the + * discrete IPE elements. This will result in greater IPE flexibility. + */ +function DrupalPanelsIPE(cache_key, cfg) { + var ipe = this; + this.key = cache_key; + this.state = {}; + this.control = $('div#panels-ipe-control-' + cache_key); + this.initButton = $('div.panels-ipe-startedit', this.control); + this.cfg = cfg; + this.changed = false; + this.sortableOptions = $.extend({ + revert: 200, + dropOnEmpty: true, // default + opacity: 0.75, // opacity of sortable while sorting + // placeholder: 'draggable-placeholder', + // forcePlaceholderSize: true, + items: 'div.panels-ipe-portlet-wrapper', + handle: 'div.panels-ipe-draghandle', + tolerance: 'pointer', + cursorAt: 'top', + update: this.setChanged, + scroll: true + // containment: ipe.topParent, + }, cfg.sortableOptions || {}); + + this.initEditing = function(formdata) { + ipe.topParent = $('div#panels-ipe-display-' + cache_key); + ipe.backup = this.topParent.clone(); + + // See http://jqueryui.com/demos/sortable/ for details on the configuration + // parameters used here. + ipe.changed = false; + + $('div.panels-ipe-sort-container', ipe.topParent).sortable(ipe.sortable_options); + + // Since the connectWith option only does a one-way hookup, iterate over + // all sortable regions to connect them with one another. + $('div.panels-ipe-sort-container', ipe.topParent) + .sortable('option', 'connectWith', ['div.panels-ipe-sort-container']); + + $('div.panels-ipe-sort-container', ipe.topParent).bind('sortupdate', function() { + ipe.changed = true; + }); + + $('.panels-ipe-form-container', ipe.control).append(formdata); + // bind ajax submit to the form + $('form', ipe.control).submit(function(event) { + url = $(this).attr('action'); + try { + var ajaxOptions = { + type: 'POST', + url: url, + data: { 'js': 1 }, + global: true, + success: Drupal.CTools.AJAX.respond, + error: function(xhr) { + Drupal.CTools.AJAX.handleErrors(xhr, url); + }, + dataType: 'json' + }; + $(this).ajaxSubmit(ajaxOptions); + } + catch (err) { + alert("An error occurred while attempting to process " + url); + return false; + } + return false; + }); + + $('input:submit', ipe.control).each(function() { + if ($(this).attr('id') == 'panels-ipe-save') { + $(this).click(ipe.saveEditing); + }; + if ($(this).attr('id') == 'panels-ipe-cancel') { + $(this).click(ipe.cancelEditing); + }; + }); + + // Perform visual effects in a particular sequence. + ipe.initButton.css('position', 'absolute'); + ipe.initButton.fadeOut('normal'); + $('.panels-ipe-on').show('normal'); +// $('.panels-ipe-on').fadeIn('normal'); + ipe.topParent.addClass('panels-ipe-editing'); + } + + this.endEditing = function(data) { + $('.panels-ipe-form-container', ipe.control).empty(); + // Re-show all the IPE non-editing meta-elements + $('div.panels-ipe-off').show('fast'); + + // Re-hide all the IPE meta-elements + $('div.panels-ipe-on').hide('fast'); + ipe.initButton.css('position', 'static'); + ipe.topParent.removeClass('panels-ipe-editing'); + $('div.panels-ipe-sort-container', ipe.topParent).sortable("destroy"); + }; + + this.saveEditing = function() { + // Put our button in. + this.form.clk = this; + + $('div.panels-ipe-region', ipe.topParent).each(function() { + var val = ''; + var region = $(this).attr('id').split('panels-ipe-regionid-')[1]; + $(this).find('div.panels-ipe-portlet-wrapper').each(function() { + var id = $(this).attr('id').split('panels-ipe-paneid-')[1]; + if (id) { + if (val) { + val += ','; + } + val += id; + } + }); + $('input#edit-panel-pane-' + region, ipe.control).val(val); + }); + } + + this.cancelEditing = function() { + // Put our button in. + this.form.clk = this; + + if (ipe.topParent.hasClass('changed')) { + ipe.changed = true; + } + + if (!ipe.changed || confirm(Drupal.t('This will discard all unsaved changes. Are you sure?'))) { + ipe.topParent.fadeOut('medium', function() { + ipe.topParent.replaceWith(ipe.backup.clone()); + ipe.topParent = $('div#panels-ipe-display-' + ipe.key); + + // Processing of these things got lost in the cloning, but the classes remained behind. + // @todo this isn't ideal but I can't seem to figure out how to keep an unprocessed backup + // that will later get processed. + $('.ctools-use-modal-processed', ipe.topParent).removeClass('ctools-use-modal-processed'); + $('.pane-delete-processed', ipe.topParent).removeClass('pane-delete-processed'); + ipe.topParent.fadeIn('medium'); + Drupal.attachBehaviors(); + }); + } + else { + // Cancel the submission. + return false; + } + }; + + this.createSortContainers = function() { + $('div.panels-ipe-region', this.topParent).each(function() { + $('div.panels-ipe-portlet-marker', this).parent() + .wrapInner('<div class="panels-ipe-sort-container" />'); + + // Move our gadgets outside of the sort container so that sortables + // cannot be placed after them. + $('div.panels-ipe-portlet-static', this).each(function() { + $(this).appendTo($(this).parent().parent()); + }); + + // Add a marker so we can drag things to empty containers. + $('div.panels-ipe-sort-container', this).append('<div> </div>'); + }); + } + + this.createSortContainers(); + + var ajaxOptions = { + type: "POST", + url: ipe.cfg.formPath, + data: { 'js': 1 }, + global: true, + success: Drupal.CTools.AJAX.respond, + error: function(xhr) { + Drupal.CTools.AJAX.handleErrors(xhr, ipe.cfg.formPath); + }, + dataType: 'json' + }; + + $('div.panels-ipe-startedit', this.control).click(function() { + var $this = $(this); + $.ajax(ajaxOptions); + }); +}; + +})(jQuery); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/panels_ipe.info b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/panels_ipe.info new file mode 100644 index 0000000000000000000000000000000000000000..afa0233bde99dc8e4a3223f6a894ecb4e7614b6e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/panels_ipe.info @@ -0,0 +1,13 @@ +name = Panels In-Place Editor +description = Provide a UI for managing some Panels directly on the frontend, instead of having to use the backend. +package = "Panels" +dependencies[] = panels +dependencies[] = jquery_ui +core = 6.x + +; Information added by drupal.org packaging script on 2012-01-18 +version = "6.x-3.10" +core = "6.x" +project = "panels" +datestamp = "1326917148" + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/panels_ipe.module b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/panels_ipe.module new file mode 100644 index 0000000000000000000000000000000000000000..4080905a5f8a449da837fadfa6c87959231419f0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/panels_ipe.module @@ -0,0 +1,147 @@ +<?php + +/** + * Implementation of hook_ctools_plugin_directory(). + */ +function panels_ipe_ctools_plugin_directory($module, $plugin) { + if ($module == 'panels' && $plugin == 'display_renderers') { + return 'plugins/' . $plugin; + } +} + +/** + * Implementation of hook_ctools_plugin_api(). + * + * Inform CTools about version information for various plugins implemented by + * Panels. + * + * @param string $owner + * The system name of the module owning the API about which information is + * being requested. + * @param string $api + * The name of the API about which information is being requested. + */ +function panels_ipe_ctools_plugin_api($owner, $api) { + if ($owner == 'panels' && $api == 'pipelines') { + return array( + 'version' => 1, + 'path' => drupal_get_path('module', 'panels_ipe') . '/includes', + ); + } +} + +/** + * Implementation of hook_theme(). + */ +function panels_ipe_theme() { + return array( + 'panels_ipe_pane_wrapper' => array( + 'arguments' => array('output' => NULL, 'pane' => NULL, 'display' => NULL), + ), + 'panels_ipe_region_wrapper' => array( + 'arguments' => array('output' => NULL, 'region_id' => NULL, 'display' => NULL, 'renderer' => NULL), + ), + 'panels_ipe_add_pane_button' => array( + 'arguments' => array('region_id' => NULL, 'display' => NULL, 'renderer' => NULL), + ), + 'panels_ipe_placeholder_pane' => array( + 'arguments' => array('region_id' => NULL, 'region_title' => NULL), + ), + 'panels_ipe_dnd_form_container' => array( + 'arguments' => array('link' => NULL, 'cache_key' => NULL, 'display' => NULL), + ), + ); +} + +/** + * Theme the 'placeholder' pane, which is shown on an active IPE when no panes + * live in that region. + * + * @param string $region_id + * @param string $region_title + */ +function theme_panels_ipe_placeholder_pane($region_id, $region_title) { + $output = '<div class="panels-ipe-placeholder-content">'; + $output .= "<h3>$region_title</h3>"; + $output .= '</div>'; + return $output; +} + +function theme_panels_ipe_pane_wrapper($output, $pane, $display, $renderer) { + $content_type = ctools_get_content_type($pane->type); + $subtype = ctools_content_get_subtype($content_type, $pane->subtype); + $links = array(); + + if (ctools_content_editable($content_type, $subtype, $pane->configuration)) { + $links['edit'] = array( + 'title' => isset($content_type['edit text']) ? $content_type['edit text'] : t('Settings'), + 'href' => $renderer->get_url('edit-pane', $pane->pid), + 'attributes' => array( + 'class' => 'ctools-use-modal', + // 'id' => "pane-edit-panel-pane-$pane->pid", + ), + ); + } + + // Deleting is managed entirely in the js; this is just an attachment point + // for it + $links['delete'] = array( + 'title' => t('Delete'), + 'href' => '#', + 'attributes' => array( + 'class' => 'pane-delete', + 'id' => "pane-delete-panel-pane-$pane->pid", + ), + ); + + $attr = array( + 'class' => 'panels-ipe-linkbar', + ); + + $links = theme('links', $links, $attr); + $links .= '<div class="panels-ipe-draghandle"> </div>'; + $handlebar = '<div class="panels-ipe-handlebar-wrapper panels-ipe-on clear-block">' . $links . '</div>'; + return $handlebar . $output; +} + +function theme_panels_ipe_region_wrapper($output, $region_id, $display) { + return $output; +} + +function theme_panels_ipe_add_pane_button($region_id, $display, $renderer) { + $attr = array('class' => 'ctools-use-modal'); + $link = l(t('Add new pane'), $renderer->get_url('select-content', $region_id), array('attributes' => $attr)); + return '<div class="panels-ipe-newblock panels-ipe-on panels-ipe-portlet-static">' . $link . '</div>'; +} + +function panels_ipe_get_cache_key($key = NULL) { + static $cache; + if (isset($key)) { + $cache = $key; + } + return $cache; +} + +/** + * Implementation of hook_footer() + * + * Adds the IPE control container. + * + * @param unknown_type $main + */ +function panels_ipe_footer($main = 0) { + $key = panels_ipe_get_cache_key(); + if (!isset($key)) { + return; + } + + // TODO should be moved into the IPE plugin - WAAAY too hardcoded right now + $output = "<div id='panels-ipe-control-container' class='clear-block'>"; + $output .= "<div id='panels-ipe-control-$key' class='panels-ipe-control'>"; + $output .= "<div class='panels-ipe-startedit panels-ipe-pseudobutton panels-ipe-off'>"; + $output .= "<span>" . t('Customize this page') . "</span>"; + $output .= "</div>"; + $output .= "<div class='panels-ipe-form-container panels-ipe-on clear-block'></div>"; + $output .= "</div></div>"; + return $output; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/plugins/display_renderers/ipe.inc b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/plugins/display_renderers/ipe.inc new file mode 100644 index 0000000000000000000000000000000000000000..afe1e444c2f5dceecaff1e238899b94e792fa437 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/plugins/display_renderers/ipe.inc @@ -0,0 +1,8 @@ +<?php + +$plugin = array( + 'handler' => array( + 'class' => 'panels_renderer_ipe', + 'parent' => 'editor', + ), +); \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/plugins/display_renderers/panels_renderer_ipe.class.php b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/plugins/display_renderers/panels_renderer_ipe.class.php new file mode 100644 index 0000000000000000000000000000000000000000..3f2c400ac728dc825dde77bc85a17820e265c7a5 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_ipe/plugins/display_renderers/panels_renderer_ipe.class.php @@ -0,0 +1,253 @@ +<?php + +/** + * Renderer class for all In-Place Editor (IPE) behavior. + */ +class panels_renderer_ipe extends panels_renderer_editor { + // The IPE operates in normal render mode, not admin mode. + var $admin = FALSE; + + function render() { + $output = parent::render(); + return "<div id='panels-ipe-display-{$this->clean_key}' class='panels-ipe-display-container'>$output</div>"; + } + + function add_meta() { + ctools_include('display-edit', 'panels'); + ctools_include('content'); + + if (empty($this->display->cache_key)) { + $this->cache = panels_edit_cache_get_default($this->display); + } + // @todo we may need an else to load the cache, but I am not sure we + // actually need to load it if we already have our cache key, and doing + // so is a waste of resources. + + ctools_include('cleanstring'); + $this->clean_key = ctools_cleanstring($this->display->cache_key); + panels_ipe_get_cache_key($this->clean_key); + + ctools_include('ajax'); + ctools_include('modal'); + ctools_modal_add_js(); + + ctools_add_css('panels_dnd', 'panels'); + ctools_add_css('panels_admin', 'panels'); + ctools_add_js('panels_ipe', 'panels_ipe'); + ctools_add_css('panels_ipe', 'panels_ipe'); + + $settings = array( + 'formPath' => url($this->get_url('save-form')), + ); + drupal_add_js(array('PanelsIPECacheKeys' => array($this->clean_key)), 'setting'); + drupal_add_js(array('PanelsIPESettings' => array($this->clean_key => $settings)), 'setting'); + + jquery_ui_add(array('ui.draggable', 'ui.droppable', 'ui.sortable')); + parent::add_meta(); + } + + /** + * Override & call the parent, then pass output through to the dnd wrapper + * theme function. + * + * @param $pane + */ + function render_pane(&$pane) { + $output = parent::render_pane($pane); + if (empty($output)) { + return; + } + + if (empty($pane->IPE_empty)) { + // Add an inner layer wrapper to the pane content before placing it into + // draggable portlet + $output = "<div class=\"panels-ipe-portlet-content\">$output</div>"; + } + else { + $output = "<div class=\"panels-ipe-portlet-content panels-ipe-empty-pane\">$output</div>"; + } + // Hand it off to the plugin/theme for placing draggers/buttons + $output = theme('panels_ipe_pane_wrapper', $output, $pane, $this->display, $this); + return "<div id=\"panels-ipe-paneid-{$pane->pid}\" class=\"panels-ipe-portlet-wrapper panels-ipe-portlet-marker\">" . $output . "</div>"; + } + + function render_pane_content(&$pane) { + $content = parent::render_pane_content($pane); + // Ensure that empty panes have some content. + if (empty($content->content)) { + // Get the administrative title. + $content_type = ctools_get_content_type($pane->type); + $title = ctools_content_admin_title($content_type, $pane->subtype, $pane->configuration, $this->display->context); + + $content->content = t('Placeholder for empty "@title"', array('@title' => $title)); + $pane->IPE_empty = TRUE; + } + + return $content; + } + + /** + * Add an 'empty' pane placeholder above all the normal panes. + * + * @param $region_id + * @param $panes + */ + function render_region($region_id, $panes) { + // Generate this region's 'empty' placeholder pane from the IPE plugin. + $empty_ph = theme('panels_ipe_placeholder_pane', $region_id, $this->plugins['layout']['panels'][$region_id]); + + // Wrap the placeholder in some guaranteed markup. + $panes['empty_placeholder'] = '<div class="panels-ipe-placeholder panels-ipe-on panels-ipe-portlet-marker panels-ipe-portlet-static">' . $empty_ph . "</div>"; + + // Generate this region's add new pane button. FIXME waaaaay too hardcoded + $panes['add_button'] = theme('panels_ipe_add_pane_button', $region_id, $this->display, $this); + + $output = parent::render_region($region_id, $panes); + $output = theme('panels_ipe_region_wrapper', $output, $region_id, $this->display); + $classes = 'panels-ipe-region'; + + ctools_include('cleanstring'); + $region_id = ctools_cleanstring($region_id); + return "<div id='panels-ipe-regionid-$region_id' class='panels-ipe-region'>$output</div>"; + } + + /** + * AJAX entry point to create the controller form for an IPE. + */ + function ajax_save_form($break = NULL) { + ctools_include('form'); + if (!empty($this->cache->locked)) { + if ($break != 'break') { + $account = user_load($this->cache->locked->uid); + $name = theme('username', $account); + $lock_age = format_interval(time() - $this->cache->locked->updated); + + $message = t("This panel is being edited by user !user, and is therefore locked from editing by others. This lock is !age old.\n\nClick OK to break this lock and discard any changes made by !user.", array('!user' => $name, '!age' => $lock_age)); + + $this->commands[] = array( + 'command' => 'unlockIPE', + 'message' => $message, + 'break_path' => url($this->get_url('save-form', 'break')) + ); + return; + } + + // Break the lock. + panels_edit_cache_break_lock($this->cache); + } + + $form_state = array( + 'display' => &$this->display, + 'content_types' => $this->cache->content_types, + 'rerender' => FALSE, + 'no_redirect' => TRUE, + // Panels needs this to make sure that the layout gets callbacks + 'layout' => $this->plugins['layout'], + ); + + $output = ctools_build_form('panels_ipe_edit_control_form', $form_state); + if ($output) { + // At this point, we want to save the cache to ensure that we have a lock. + panels_edit_cache_set($this->cache); + $this->commands[] = array( + 'command' => 'initIPE', + 'key' => $this->clean_key, + 'data' => $output, + ); + return; + } + + // no output == submit + if (!empty($form_state['clicked_button']['#save-display'])) { + // Saved. Save the cache. + panels_edit_cache_save($this->cache); + } + else { + // Cancelled. Clear the cache. + panels_edit_cache_clear($this->cache); + } + + $this->commands[] = array( + 'command' => 'endIPE', + 'key' => $this->clean_key, + 'data' => $output, + ); + } + + /** + * Create a command array to redraw a pane. + */ + function command_update_pane($pid) { + if (is_object($pid)) { + $pane = $pid; + } + else { + $pane = $this->display->content[$pid]; + } + + $this->commands[] = ctools_ajax_command_replace("#panels-ipe-paneid-$pane->pid", $this->render_pane($pane)); + $this->commands[] = ctools_ajax_command_changed("#panels-ipe-display-{$this->clean_key}"); + } + + /** + * Create a command array to add a new pane. + */ + function command_add_pane($pid) { + if (is_object($pid)) { + $pane = $pid; + } + else { + $pane = $this->display->content[$pid]; + } + + ctools_include('cleanstring'); + $region_id = ctools_cleanstring($pane->panel); + $this->commands[] = ctools_ajax_command_append("#panels-ipe-regionid-$region_id div.panels-ipe-sort-container", $this->render_pane($pane)); + $this->commands[] = ctools_ajax_command_changed("#panels-ipe-display-{$this->clean_key}"); + } +} + +/** + * FAPI callback to create the Save/Cancel form for the IPE. + */ +function panels_ipe_edit_control_form(&$form_state) { + $display = &$form_state['display']; + // @todo -- this should be unnecessary as we ensure cache_key is set in add_meta() +// $display->cache_key = isset($display->cache_key) ? $display->cache_key : $display->did; + + // Annoyingly, theme doesn't have access to form_state so we have to do this. + $form['#display'] = $display; + + $layout = panels_get_layout($display->layout); + $layout_panels = panels_get_regions($layout, $display); + + $form['panel'] = array('#tree' => TRUE); + $form['panel']['pane'] = array('#tree' => TRUE); + + foreach ($layout_panels as $panel_id => $title) { + // Make sure we at least have an empty array for all possible locations. + if (!isset($display->panels[$panel_id])) { + $display->panels[$panel_id] = array(); + } + + $form['panel']['pane'][$panel_id] = array( + // Use 'hidden' instead of 'value' so the js can access it. + '#type' => 'hidden', + '#default_value' => implode(',', (array) $display->panels[$panel_id]), + ); + } + + $form['buttons']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + '#id' => 'panels-ipe-save', + '#submit' => array('panels_edit_display_form_submit'), + '#save-display' => TRUE, + ); + $form['buttons']['cancel'] = array( + '#type' => 'submit', + '#value' => t('Cancel'), + '#id' => 'panels-ipe-cancel', + ); + return $form; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.admin.inc b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..0dd049fdf9d5994d26b50c5ebb040d8df1017189 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.admin.inc @@ -0,0 +1,41 @@ +<?php + +/** + * @file + * + * Administrative items for the panels mini module. + */ +/** + * Implementation of hook_menu(). + */ +function _panels_mini_menu() { + // Provide some common options to reduce code repetition. + // By using array addition and making sure these are the rightmost + // value, they won't override anything already set. + $base = array( + 'access arguments' => array('create mini panels'), + 'file' => 'panels_mini.admin.inc', + ); + + $items['admin/build/mini-panels/settings'] = array( + 'title' => 'Settings', + 'page callback' => 'panels_mini_settings', + 'type' => MENU_LOCAL_TASK, + ) + $base; + // Also provide settings on the main panel UI + $items['admin/build/panels/settings/panels-mini'] = array( + 'title' => 'Mini panels', + 'page callback' => 'panels_mini_settings', + 'type' => MENU_LOCAL_TASK, + ) + $base; + + return $items; +} + +/** + * Settings for mini panels. + */ +function panels_mini_settings() { + ctools_include('common', 'panels'); + return drupal_get_form('panels_common_settings', 'panels_mini'); +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.info b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.info new file mode 100644 index 0000000000000000000000000000000000000000..d09dba25c424a30fc04dd9b8d205426e449a0af7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.info @@ -0,0 +1,11 @@ +name = Mini panels +description = Create mini panels that can be used as blocks by Drupal and panes by other panel modules. +package = "Panels" +dependencies[] = panels +core = 6.x +; Information added by drupal.org packaging script on 2012-01-18 +version = "6.x-3.10" +core = "6.x" +project = "panels" +datestamp = "1326917148" + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.install b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.install new file mode 100644 index 0000000000000000000000000000000000000000..3e4563650f7ea3c1093b00c25cd6898bcda71fdf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.install @@ -0,0 +1,185 @@ +<?php + +/** + * Implementation of hook_schema(). + */ +function panels_mini_schema() { + // This should always point to our 'current' schema. This makes it relatively easy + // to keep a record of schema as we make changes to it. + return panels_mini_schema_1(); +} + +/** + * Schema version 1 for Panels in D6. + */ +function panels_mini_schema_1() { + $schema = array(); + + $schema['panels_mini'] = array( + 'export' => array( + 'identifier' => 'mini', + 'load callback' => 'panels_mini_load', + 'load all callback' => 'panels_mini_load_all', + 'save callback' => 'panels_mini_save', + 'delete callback' => 'panels_mini_delete', + 'export callback' => 'panels_mini_export', + 'api' => array( + 'owner' => 'panels_mini', + 'api' => 'panels_default', + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), + 'fields' => array( + 'pid' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'no export' => TRUE, + 'description' => 'The primary key for uniqueness.', + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => 'The unique name of the mini panel.', + ), + 'category' => array( + 'type' => 'varchar', + 'length' => '64', + 'description' => 'The category this mini panel appears in on the add content pane.', + ), + 'did' => array( + 'type' => 'int', + 'no export' => TRUE, + 'description' => 'The display ID of the panel.', + ), + 'admin_title' => array( + 'type' => 'varchar', + 'length' => '128', + 'description' => 'The administrative title of the mini panel.', + ), + 'admin_description' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Administrative title of this mini panel.', + 'object default' => '', + ), + 'requiredcontexts' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'description' => 'An array of required contexts.', + ), + 'contexts' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'description' => 'An array of contexts embedded into the panel.', + ), + 'relationships' => array( + 'type' => 'text', + 'size' => 'big', + 'serialize' => TRUE, + 'object default' => array(), + 'description' => 'An array of relationships embedded into the panel.', + ), + ), + 'primary key' => array('pid'), + 'unique keys' => array( + 'name' => array('name'), + ), + ); + + return $schema; +} + +/** + * Implementation of hook_install(). + */ +function panels_mini_install() { + drupal_install_schema('panels_mini'); +} + +/** + * Implementation of hook_uninstall(). + */ +function panels_mini_uninstall() { + $result = db_query("SELECT * FROM {panels_mini}"); + $panels_exists = db_table_exists('panels_display'); + while ($panel_mini = db_fetch_object($result)) { + // Delete all associated displays. + if (!function_exists('panels_delete_display')) { + require_once drupal_get_path('module', 'panels') .'/panels.module'; + } + if ($panels_exists) { + panels_delete_display($panel_mini->did); + } + + // Delete all configured blocks. + db_query("DELETE FROM {blocks} WHERE module = 'panels_mini' AND delta = %d", $panel_mini->pid); + } + + // Finally, delete all mini panels. + drupal_uninstall_schema('panels_mini'); +} + +/** + * Update all blocks to use 'name' as delta, not 'pid'. + */ +function panels_mini_update_6300() { + $ret = array(); + $result = db_query("SELECT name, pid from {panels_mini}"); + while ($mini = db_fetch_object($result)) { + db_query("UPDATE {blocks} SET delta = '%s' WHERE module = 'panels_mini' AND delta = %d", $mini->name, $mini->pid); + } + return $ret; +} + +/** + * Update all panel mini blocks to not use block caching. + */ +function panels_mini_update_6301() { + $ret = array(); + $ret[] = update_sql("UPDATE {blocks} SET cache = -1 WHERE module = 'panels_mini'"); + return $ret; +} + +/** + * Add the admin description field. + */ +function panels_mini_update_6302() { + $ret = array(); + $field = array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Administrative description of this mini panel.', + 'object default' => '', + ); + + db_add_field($ret, 'panels_mini', 'admin_description', $field); + return $ret; +} + +/** + * Add the admin description field. + */ +function panels_mini_update_6303() { + $ret = array(); + $field = array( + 'type' => 'varchar', + 'length' => '128', + 'description' => 'The administrative title of the mini panel.', + ); + + db_add_field($ret, 'panels_mini', 'admin_title', $field); + + $result = db_query("SELECT pid, did, title FROM {panels_mini}"); + while ($mini = db_fetch_object($result)) { + db_query("UPDATE {panels_mini} SET admin_title = '%s' WHERE pid = %d", $mini->title, $mini->pid); + db_query("UPDATE {panels_display} SET title = '%s' WHERE did = %d", $mini->title, $mini->pid); + } + + db_drop_field($ret, 'panels_mini', 'title'); + return $ret; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.module b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.module new file mode 100644 index 0000000000000000000000000000000000000000..7b42fc40677fba1c44add602ace2c804e135b97c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/panels_mini.module @@ -0,0 +1,397 @@ +<?php + +/** + * @file panels_mini.module + * + * This module provides mini panels which are basically panels that can be + * used within blocks or other panels. + */ + +/** + * Implementation of hook_perm(). + */ +function panels_mini_perm() { + return array('create mini panels', 'administer mini panels'); +} + +/** + * Implementation of hook_menu(). + */ +function panels_mini_menu() { + // Safety: go away if CTools is not at an appropriate version. + if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + return array(); + } + require_once drupal_get_path('module', 'panels_mini') . '/panels_mini.admin.inc'; + return _panels_mini_menu(); +} + +// --------------------------------------------------------------------------- +// Allow the rest of the system access to mini panels + +/** + * Implementation of hook_block(). + * + * Expose qualifying mini panels to Drupal's block system. + */ +function panels_mini_block($op = 'list', $delta = 0, $edit = array()) { + // Safety: go away if CTools is not at an appropriate version. + if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + return array(); + } + + if ($op == 'list') { + $blocks = array(); + + $minis = panels_mini_load_all(); + foreach ($minis as $panel_mini) { + if (empty($mini->disabled) && empty($mini->requiredcontext)) { + $blocks[$panel_mini->name] = array( + 'info' => t('Mini panel: "@title"', array('@title' => $panel_mini->admin_title)), + 'cache' => BLOCK_NO_CACHE, + ); + } + } + + return $blocks; + } + elseif ($op == 'view') { + // static recursion protection. + static $viewing = array(); + if (!empty($viewing[$delta])) { + return; + } + $viewing[$delta] = TRUE; + + $panel_mini = panels_mini_load($delta); + if (empty($panel_mini)) { + // Bail out early if the specified mini panel doesn't exist. + return; + } + + ctools_include('context'); + $panel_mini->context = $panel_mini->display->context = ctools_context_load_contexts($panel_mini); + $panel_mini->display->css_id = panels_mini_get_id($panel_mini->name); + + $block = array(); + + $block['content'] = panels_render_display($panel_mini->display); + $block['subject'] = $panel_mini->display->get_title(); + + unset($viewing[$delta]); + return $block; + } + elseif ($op = 'configure') { + return array( + 'admin-shortcut' => array( + '#value' => l(t('Manage this mini-panel'), "admin/build/mini-panels/list/$delta/edit") + ), + ); + } +} + +/** + * Statically store all used IDs to ensure all mini panels get a unique id. + */ +function panels_mini_get_id($name) { + static $id_cache = array(); + + $id = 'mini-panel-' . $name; + if (!empty($id_cache[$name])) { + $id .= "-" . $id_cache[$name]++; + } + else { + $id_cache[$name] = 1; + } + + return $id; +} + +// --------------------------------------------------------------------------- +// Database functions. + +/** + * Create a new page with defaults appropriately set from schema. + */ +function panels_mini_new($set_defaults = TRUE) { + ctools_include('export'); + return ctools_export_new_object('panels_mini', $set_defaults); +} + +/** + * Load a single mini panel. + */ +function panels_mini_load($name) { + $cache = &ctools_static('panels_mini_load_all', array()); + + // We use array_key_exists because failed loads will be NULL and + // isset() will try to load it again. + if (!array_key_exists($name, $cache)) { + ctools_include('export'); + $result = ctools_export_load_object('panels_mini', 'names', array($name)); + if (isset($result[$name])) { + if (empty($result[$name]->display)) { + $result[$name]->display = panels_load_display($result[$name]->did); + if (!empty($result[$name]->title) && empty($result[$name]->display->title)) { + $result[$name]->display->title = $result[$name]->title; + } + } + $cache[$name] = $result[$name]; + if (!empty($result[$name]->title) && empty($result[$name]->admin_title)) { + $cache[$name]->admin_title = $result[$name]->title; + } + } + else { + $cache[$name] = NULL; + } + } + + if (isset($cache[$name])) { + return $cache[$name]; + } +} + +/** + * Load all mini panels. + */ +function panels_mini_load_all($reset = FALSE) { + $cache = &ctools_static('panels_mini_load_all', array()); + static $all_loaded = FALSE; + + // We check our own private static because individual minis could have + // been loaded prior to load all and we need to know that. + if (!$all_loaded || $reset) { + $all_loaded = TRUE; + if ($reset) { + $cache = array(); + } + + ctools_include('export'); + $minis = ctools_export_load_object('panels_mini'); + $dids = array(); + foreach ($minis as $mini) { + if (empty($cache[$mini->name])) { + if (!empty($mini->did)) { + $dids[$mini->did] = $mini->name; + } + else { + // Translate old style titles into new titles. + if (!empty($mini->title) && empty($mini->display->title)) { + $mini->display->title = $mini->title; + } + } + // Translate old style titles into new titles. + if (isset($mini->title) && empty($mini->admin_title)) { + $mini->admin_title = $mini->title; + } + $cache[$mini->name] = $mini; + } + } + + $displays = panels_load_displays(array_keys($dids)); + foreach ($displays as $did => $display) { + if (!empty($cache[$dids[$did]]->title) && empty($display->title)) { + $display->title = $cache[$dids[$did]]->title; + } + $cache[$dids[$did]]->display = $display; + } + } + + return $cache; +} + +/** + * Write a mini panel to the database. + */ +function panels_mini_save(&$mini) { + if (!empty($mini->display)) { + $display = panels_save_display($mini->display); + $mini->did = $display->did; + } + + $update = (isset($mini->pid) && $mini->pid != 'new') ? array('pid') : array(); + drupal_write_record('panels_mini', $mini, $update); + + return $mini; +} + +/** + * Remove a mini panel. + */ +function panels_mini_delete($mini) { + db_query("DELETE FROM {panels_mini} WHERE name = '%s'", $mini->name); + if ($mini->type != t('Overridden')) { + db_query("DELETE FROM {blocks} WHERE module = 'panels_mini' AND delta = '%s'", $mini->name); + } + return panels_delete_display($mini->did); +} + +/** + * Export a mini panel. + */ +function panels_mini_export($mini, $indent = '') { + ctools_include('export'); + $output = ctools_export_object('panels_mini', $mini, $indent); + // Export the primary display + $display = !empty($mini->display) ? $mini->display : panels_load_display($mini->did); + $output .= panels_export_display($display, $indent); + $output .= $indent . '$mini->display = $display' . ";\n"; + return $output; +} + +/** + * Remove the block version of mini panels from being available content types. + */ +function panels_mini_ctools_block_info($module, $delta, &$info) { + $info = NULL; +} + +/** + * Implementation of hook_ctools_plugin_directory() to let the system know + * we implement task and task_handler plugins. + */ +function panels_mini_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && ($plugin == 'content_types' || $plugin == 'export_ui')) { + return 'plugins/' . $plugin; + } +} + +/** + * Get the display cache for the panels_mini plugin. + */ +function _panels_mini_panels_cache_get($key) { + ctools_include('export-ui'); + $plugin = ctools_get_export_ui('panels_mini'); + $handler = ctools_export_ui_get_handler($plugin); + if (!$handler) { + return; + } + + $item = $handler->edit_cache_get($key); + if (!$item) { + $item = ctools_export_crud_load($handler->plugin['schema'], $key); + } + + return array($handler, $item); +} + +/** + * Get display edit cache for the panels mini export UI + * + * The key is the second half of the key in this form: + * panels_mini:TASK_NAME:HANDLER_NAME; + */ +function panels_mini_panels_cache_get($key) { + ctools_include('common', 'panels'); + list($handler, $item) = _panels_mini_panels_cache_get($key); + if (isset($item->mini_panels_display_cache)) { + return $item->mini_panels_display_cache; + } + + $cache = new stdClass(); + $cache->display = $item->display; + $cache->display->context = ctools_context_load_contexts($item); + $cache->display->cache_key = 'panels_mini:' . $key; + $cache->content_types = panels_common_get_allowed_types('panels_mini', $cache->display->context); + $cache->display_title = TRUE; + + // @TODO support locking + $cache->locked = FALSE; + + return $cache; +} + +/** + * Store a display edit in progress in the page cache. + */ +function panels_mini_panels_cache_set($key, $cache) { + list($handler, $item) = _panels_mini_panels_cache_get($key); + $item->mini_panels_display_cache = $cache; + $handler->edit_cache_set_key($item, $key); +} + +/** + * Save all changes made to a display using the panels mini UI cache. + */ +function panels_mini_panels_cache_clear($key, $cache) { + list($handler, $item) = _panels_mini_panels_cache_get($key); + $handler->edit_cache_clear($item); +} + +/** + * Save all changes made to a display using the panels mini UI cache. + */ +function panels_mini_panels_cache_save($key, $cache) { + list($handler, $item) = _panels_mini_panels_cache_get($key); + $item->display = $cache->display; + panels_mini_save($item); + + $handler->edit_cache_clear($item); +} + +/** + * Break the lock on a panels mini page. + */ +function panels_mini_panels_cache_break_lock($key, $cache) { +} + +/** + * Alter default mini panels to ensure they have new fields and avoid warnings. + */ +function panels_mini_default_panels_mini_alter(&$minis) { + foreach ($minis as $name => $mini) { + if (!isset($mini->admin_description)) { + $minis[$name]->admin_description = ''; + } + } +} + +/** + * Implementation of hook_panels_dashboard_blocks(). + * + * Adds mini panels information to the Panels dashboard. + */ +function panels_mini_panels_dashboard_blocks(&$vars) { + $vars['links']['panels_mini'] = array( + 'title' => l(t('Mini panel'), 'admin/build/mini-panels/add'), + 'description' => t('Mini panels are small content areas exposed as blocks, for when you need to have complex block layouts or layouts within layouts.'), + 'weight' => -1, + ); + + // Load all mini panels and their displays. + $panel_minis = panels_mini_load_all(); + $count = 0; + $rows = array(); + + foreach ($panel_minis as $panel_mini) { + $rows[] = array( + check_plain($panel_mini->admin_title), + array( + 'data' => l(t('Edit'), "admin/build/mini-panels/list/$panel_mini->name/edit"), + 'class' => 'links', + ), + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + + if ($rows) { + $content = theme('table', array(), $rows, array('class' => 'panels-manage')); + } + else { + $content = '<p>' . t('There are no mini panels.') . '</p>'; + } + + $vars['blocks']['panels_mini'] = array( + 'weight' => -100, + 'title' => t('Manage mini panels'), + 'link' => l(t('Go to list'), 'admin/build/mini-panels'), + 'content' => $content, + 'class' => 'dashboard-mini-panels', + 'section' => 'left', + ); + +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/content_types/icon_panels_mini.png b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/content_types/icon_panels_mini.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0891b03d97142074cabbe5ed47175ad01c838e Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/content_types/icon_panels_mini.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/content_types/panels_mini.inc b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/content_types/panels_mini.inc new file mode 100644 index 0000000000000000000000000000000000000000..9857738694c3bfcfaab40cd719dc7f9cc4be97fe --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/content_types/panels_mini.inc @@ -0,0 +1,133 @@ +<?php + +/** + * @file + * Contains the content type plugin for a mini panel. While this does not + * need to be broken out into a .inc file, it's convenient that we do so + * that we don't load code unneccessarily. Plus it demonstrates plugins + * in modules other than Panels itself. + * + */ + +/** + * Specially named hook. for .inc file. This looks a little silly due to the + * redundancy, but that's really just because the content type shares a + * name with the module. + */ +function panels_mini_panels_mini_ctools_content_types() { + return array( + 'title' => t('Mini panels'), + 'content type' => 'panels_mini_panels_mini_content_type_content_type', + ); +} + +/** + * Return each available mini panel available as a subtype. + */ +function panels_mini_panels_mini_content_type_content_type($subtype_id, $plugin) { + $mini = panels_mini_load($subtype_id); + return _panels_mini_panels_mini_content_type_content_type($mini); +} + +/** + * Return each available mini panel available as a subtype. + */ +function panels_mini_panels_mini_content_type_content_types($plugin) { + $types = array(); + foreach (panels_mini_load_all() as $mini) { + $type = _panels_mini_panels_mini_content_type_content_type($mini); + if ($type) { + $types[$mini->name] = $type; + } + } + return $types; +} + +/** + * Return an info array describing a single mini panel. + */ +function _panels_mini_panels_mini_content_type_content_type($mini) { + if (!empty($mini->disabled)) { + return; + } + + $title = filter_xss_admin($mini->admin_title); + $type = array( + 'title' => $title, + // For now mini panels will just use the contrib block icon. + 'icon' => 'icon_mini_panel.png', + 'description' => $title, + 'category' => !empty($mini->category) ? $mini->category : t('Mini panel'), + ); + if (!empty($mini->requiredcontexts)) { + $type['required context'] = array(); + foreach ($mini->requiredcontexts as $context) { + $info = ctools_get_context($context['name']); + // TODO: allow an optional setting + $type['required context'][] = new ctools_context_required($context['identifier'], $info['context name']); + } + } + return $type; +} + +/** + * Render a mini panel called from a panels display. + */ +function panels_mini_panels_mini_content_type_render($subtype, $conf, $panel_args, &$contexts) { + static $viewing = array(); + $mini = panels_mini_load($subtype); + if (!$mini) { + return FALSE; + } + if (!empty($viewing[$mini->name])) { + return FALSE; + } + + // Load up any contexts we might be using. + $context = ctools_context_match_required_contexts($mini->requiredcontexts, $contexts); + $mini->context = $mini->display->context = ctools_context_load_contexts($mini, FALSE, $context); + + if (empty($mini) || !empty($mini->disabled)) { + return; + } + $viewing[$mini->name] = TRUE; + + $mini->display->args = $panel_args; + $mini->display->css_id = panels_mini_get_id($subtype); + $mini->display->owner = $mini; + // unique ID of this mini. + $mini->display->owner->id = $mini->name; + + $block = new stdClass(); + $block->module = 'panels_mini'; + $block->delta = $subtype; + $block->content = panels_render_display($mini->display); + $block->title = $mini->display->get_title(); + + unset($viewing[$mini->name]); + return $block; +} + +/** + * Edit form for the mini panel content type. + */ +function panels_mini_panels_mini_content_type_edit_form(&$form, &$form_state) { + // Empty form to ensure we have the override title + context gadgets. +} + +/** + * Provide the administrative title of a mini panel. + */ +function panels_mini_panels_mini_content_type_admin_title($subtype, $conf) { + $mini = panels_mini_load($subtype); + if (!$mini) { + return t('Deleted/missing mini panel @name', array('@name' => $subtype)); + } + + $title = filter_xss_admin($mini->admin_title); + if (empty($title)) { + $title = t('Untitled mini panel'); + } + return $title; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/export_ui/panels_mini.inc b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/export_ui/panels_mini.inc new file mode 100644 index 0000000000000000000000000000000000000000..46cb894716419351db1494289aebdeb4030392a2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/export_ui/panels_mini.inc @@ -0,0 +1,41 @@ +<?php + +$plugin = array( + 'schema' => 'panels_mini', + 'access' => 'administer mini panels', + 'create access' => 'create mini panels', + + 'menu' => array( + 'menu item' => 'mini-panels', + 'menu title' => 'Mini panels', + 'menu description' => 'Add, edit or delete mini panels, which can be used as blocks or content panes in other panels.', + ), + + 'title singular' => t('mini panel'), + 'title singular proper' => t('Mini panel'), + 'title plural' => t('mini panels'), + 'title plural proper' => t('Mini panels'), + + 'handler' => array( + 'class' => 'panels_mini_ui', + 'parent' => 'ctools_export_ui', + ), + + 'use wizard' => TRUE, + 'form info' => array( + 'order' => array( + 'basic' => t('Settings'), + 'context' => t('Context'), + 'layout' => t('Layout'), + 'content' => t('Content'), + ), + // We have to add this form specially because it's invisible. + 'forms' => array( + 'move' => array( + 'form id' => 'ctools_export_ui_edit_item_wizard_form', + ), + ), + ), + +); + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/export_ui/panels_mini_ui.class.php b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/export_ui/panels_mini_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..2db6857d2040231b52500701071669e82d4bac96 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_mini/plugins/export_ui/panels_mini_ui.class.php @@ -0,0 +1,291 @@ +<?php + +class panels_mini_ui extends ctools_export_ui { + function init($plugin) { + parent::init($plugin); + ctools_include('context'); + } + + function list_form(&$form, &$form_state) { + ctools_include('plugins', 'panels'); + $this->layouts = panels_get_layouts(); + + parent::list_form($form, $form_state); + + $categories = $layouts = array('all' => t('- All -')); + foreach ($this->items as $item) { + $categories[$item->category] = $item->category ? $item->category : t('Mini panels'); + } + + $form['top row']['category'] = array( + '#type' => 'select', + '#title' => t('Category'), + '#options' => $categories, + '#default_value' => 'all', + '#weight' => -10, + ); + + foreach ($this->layouts as $name => $plugin) { + $layouts[$name] = $plugin['title']; + } + + $form['top row']['layout'] = array( + '#type' => 'select', + '#title' => t('Layout'), + '#options' => $layouts, + '#default_value' => 'all', + '#weight' => -9, + ); + } + + function list_filter($form_state, $item) { + if ($form_state['values']['category'] != 'all' && $form_state['values']['category'] != $item->category) { + return TRUE; + } + + if ($form_state['values']['layout'] != 'all' && $form_state['values']['layout'] != $item->display->layout) { + return TRUE; + } + + return parent::list_filter($form_state, $item); + } + + function list_sort_options() { + return array( + 'disabled' => t('Enabled, title'), + 'title' => t('Title'), + 'name' => t('Name'), + 'category' => t('Category'), + 'storage' => t('Storage'), + 'layout' => t('Layout'), + ); + } + + function list_build_row($item, &$form_state, $operations) { + // Set up sorting + switch ($form_state['values']['order']) { + case 'disabled': + $this->sorts[$item->name] = empty($item->disabled) . $item->admin_title; + break; + case 'title': + $this->sorts[$item->name] = $item->admin_title; + break; + case 'name': + $this->sorts[$item->name] = $item->name; + break; + case 'category': + $this->sorts[$item->name] = ($item->category ? $item->category : t('Mini panels')) . $item->admin_title; + break; + case 'layout': + $this->sorts[$item->name] = $item->display->layout . $item->admin_title; + break; + case 'storage': + $this->sorts[$item->name] = $item->type . $item->admin_title; + break; + } + + $layout = !empty($this->layouts[$item->display->layout]) ? $this->layouts[$item->display->layout]['title'] : t('Missing layout'); + $category = $item->category ? check_plain($item->category) : t('Mini panels'); + + $this->rows[$item->name] = array( + 'data' => array( + array('data' => check_plain($item->admin_title), 'class' => 'ctools-export-ui-title'), + array('data' => check_plain($item->name), 'class' => 'ctools-export-ui-name'), + array('data' => $category, 'class' => 'ctools-export-ui-category'), + array('data' => $layout, 'class' => 'ctools-export-ui-layout'), + array('data' => $item->type, 'class' => 'ctools-export-ui-storage'), + array('data' => theme('links', $operations), 'class' => 'ctools-export-ui-operations'), + ), + 'title' => !empty($item->admin_description) ? check_plain($item->admin_description) : '', + 'class' => !empty($item->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled', + ); + } + + function list_table_header() { + return array( + array('data' => t('Title'), 'class' => 'ctools-export-ui-title'), + array('data' => t('Name'), 'class' => 'ctools-export-ui-name'), + array('data' => t('Category'), 'class' => 'ctools-export-ui-category'), + array('data' => t('Layout'), 'class' => 'ctools-export-ui-layout'), + array('data' => t('Storage'), 'class' => 'ctools-export-ui-storage'), + array('data' => t('Operations'), 'class' => 'ctools-export-ui-operations'), + ); + } + + function edit_form(&$form, &$form_state) { + // Get the basic edit form + parent::edit_form($form, $form_state); + + $form['category'] = array( + '#type' => 'textfield', + '#size' => 24, + '#default_value' => $form_state['item']->category, + '#title' => t('Category'), + '#description' => t("The category that this mini-panel will be grouped into on the Add Content form. Only upper and lower-case alphanumeric characters are allowed. If left blank, defaults to 'Mini panels'."), + ); + + $form['title']['#title'] = t('Title'); + $form['title']['#description'] = t('The title for this mini panel. It can be overridden in the block configuration.'); + } + + /** + * Validate submission of the mini panel edit form. + */ + function edit_form_basic_validate($form, &$form_state) { + parent::edit_form_validate($form, $form_state); + if (preg_match("/[^A-Za-z0-9 ]/", $form_state['values']['category'])) { + form_error($form['category'], t('Categories may contain only alphanumerics or spaces.')); + } + } + + function edit_form_submit(&$form, &$form_state) { + parent::edit_form_submit($form, $form_state); + $form_state['item']->category = $form_state['values']['category']; + } + + function edit_form_context(&$form, &$form_state) { + ctools_include('context-admin'); + ctools_context_admin_includes(); + ctools_add_css('ruleset'); + + $form['right'] = array( + '#prefix' => '<div class="ctools-right-container">', + '#suffix' => '</div>', + ); + + $form['left'] = array( + '#prefix' => '<div class="ctools-left-container clear-block">', + '#suffix' => '</div>', + ); + + // Set this up and we can use CTools' Export UI's built in wizard caching, + // which already has callbacks for the context cache under this name. + $module = 'ctools_export_ui-' . $this->plugin['name']; + $name = $this->edit_cache_get_key($form_state['item'], $form_state['form type']); + + ctools_context_add_context_form($module, $form, $form_state, $form['right']['contexts_table'], $form_state['item'], $name); + ctools_context_add_required_context_form($module, $form, $form_state, $form['left']['required_contexts_table'], $form_state['item'], $name); + ctools_context_add_relationship_form($module, $form, $form_state, $form['right']['relationships_table'], $form_state['item'], $name); + } + + function edit_form_context_submit(&$form, &$form_state) { + // Prevent this from going to edit_form_submit(); + } + + function edit_form_layout(&$form, &$form_state) { + ctools_include('common', 'panels'); + ctools_include('display-layout', 'panels'); + ctools_include('plugins', 'panels'); + + // @todo -- figure out where/how to deal with this. + $form_state['allowed_layouts'] = 'panels_mini'; + + if ($form_state['op'] == 'add' && empty($form_state['item']->display)) { + $form_state['item']->display = panels_new_display(); + } + + $form_state['display'] = &$form_state['item']->display; + + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + + // Change the #id of the form so the CSS applies properly. + $form['#id'] = 'panels-choose-layout'; + $form = array_merge($form, panels_choose_layout($form_state)); + + if ($form_state['op'] == 'edit') { + $form['buttons']['next']['#value'] = t('Change'); + } + } + + /** + * Validate that a layout was chosen. + */ + function edit_form_layout_validate(&$form, &$form_state) { + $display = &$form_state['display']; + if (empty($form_state['values']['layout'])) { + form_error($form['layout'], t('You must select a layout.')); + } + if ($form_state['op'] == 'edit') { + if ($form_state['values']['layout'] == $display->layout) { + form_error($form['layout'], t('You must select a different layout if you wish to change layouts.')); + } + } + } + + /** + * A layout has been selected, set it up. + */ + function edit_form_layout_submit(&$form, &$form_state) { + $display = &$form_state['display']; + if ($form_state['op'] == 'edit') { + if ($form_state['values']['layout'] != $display->layout) { + $form_state['item']->temp_layout = $form_state['values']['layout']; + $form_state['clicked_button']['#next'] = 'move'; + } + } + else { + $form_state['item']->display->layout = $form_state['values']['layout']; + } + } + + /** + * When a layout is changed, the user is given the opportunity to move content. + */ + function edit_form_move(&$form, &$form_state) { + $form_state['display'] = &$form_state['item']->display; + $form_state['layout'] = $form_state['item']->temp_layout; + + ctools_include('common', 'panels'); + ctools_include('display-layout', 'panels'); + ctools_include('plugins', 'panels'); + + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + + // Change the #id of the form so the CSS applies properly. + $form = array_merge($form, panels_change_layout($form_state)); + + // This form is outside the normal wizard list, so we need to specify the + // previous/next forms. + $form['buttons']['previous']['#next'] = 'layout'; + $form['buttons']['next']['#next'] = 'content'; + } + + function edit_form_move_submit(&$form, &$form_state) { + panels_change_layout_submit($form, $form_state); + } + + function edit_form_content(&$form, &$form_state) { + ctools_include('ajax'); + ctools_include('plugins', 'panels'); + ctools_include('display-edit', 'panels'); + ctools_include('context'); + + // If we are cloning an item, we MUST have this cached for this to work, + // so make sure: + if ($form_state['form type'] == 'clone' && empty($form_state['item']->export_ui_item_is_cached)) { + $this->edit_cache_set($form_state['item'], 'clone'); + } + + $cache = panels_edit_cache_get('panels_mini:' . $this->edit_cache_get_key($form_state['item'], $form_state['form type'])); + + $form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display); + $form_state['renderer']->cache = &$cache; + + $form_state['display'] = &$cache->display; + $form_state['content_types'] = $cache->content_types; + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + $form_state['display_title'] = !empty($cache->display_title); + + $form = array_merge($form, panels_edit_display_form($form_state)); + // Make sure the theme will work since our form id is different. + $form['#theme'] = 'panels_edit_display_form'; + } + + function edit_form_content_submit(&$form, &$form_state) { + panels_edit_display_form_submit($form, $form_state); + $form_state['item']->display = $form_state['display']; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.info b/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.info new file mode 100644 index 0000000000000000000000000000000000000000..2ac62677e0a936e66e398c6d74e89e042b879381 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.info @@ -0,0 +1,13 @@ +name = Panel nodes +description = Create nodes that are divided into areas with selectable content. +package = "Panels" +dependencies[] = panels +core = 6.x + + +; Information added by drupal.org packaging script on 2012-01-18 +version = "6.x-3.10" +core = "6.x" +project = "panels" +datestamp = "1326917148" + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.install b/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.install new file mode 100644 index 0000000000000000000000000000000000000000..b171b67ddd3a6744a5ea1f08a0dfb7c7d6e892ac --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.install @@ -0,0 +1,73 @@ +<?php + +/** + * Implementation of hook_schema(). + */ +function panels_node_schema() { + // This should always point to our 'current' schema. This makes it relatively easy + // to keep a record of schema as we make changes to it. + return panels_node_schema_1(); +} + +/** + * Schema version 1 for Panels in D6. + */ +function panels_node_schema_1() { + $schema = array(); + + $schema['panels_node'] = array( + 'fields' => array( + 'nid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'css_id' => array( + 'type' => 'varchar', + 'length' => '255', + ), + 'did' => array( + 'type' => 'int', + 'not null' => TRUE, + ), + 'pipeline' => array( + 'type' => 'varchar', + 'length' => '255', + ), + ), + 'primary key' => array('did'), + ); + + return $schema; +} + +/** + * Implementation of hook_install(). + */ +function panels_node_install() { + db_query("UPDATE {system} SET weight = 11 WHERE name = 'panels_node'"); + drupal_install_schema('panels_node'); +} + +/** + * Implementation of hook_uninstall(). + */ +function panels_node_uninstall() { + // TODO: Delete all actual nodes that are panels_nodes. + db_query("DELETE FROM {node} WHERE type = 'panel'"); + drupal_uninstall_schema('panels_node'); +} + +/** + * Implementation of hook_update to handle adding a pipeline + */ +function panels_node_update_6001() { + $ret = array(); + $field = array( + 'type' => 'varchar', + 'length' => '255', + ); + + db_add_field($ret, 'panels_node', 'pipeline', $field); + return $ret; +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.module b/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.module new file mode 100644 index 0000000000000000000000000000000000000000..ffd26939f0189d8a8bb390280518609b58561cde --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/panels_node/panels_node.module @@ -0,0 +1,408 @@ +<?php + + +/** + * @file panels_node.module + * + * This module provides the "panel" node type. + * Panel nodes are useful to add additional content to the content area + * on a per-node base. + */ + +// --------------------------------------------------------------------------- +// General Drupal hooks + +/** + * Implementation of hook_perm(). + */ +function panels_node_perm() { + return array('create panel-nodes', 'edit any panel-nodes', 'edit own panel-nodes', 'administer panel-nodes', 'delete any panel-nodes', 'delete own panel-nodes'); +} + +/** + * Implementation of hook_menu(). + */ +function panels_node_menu() { + // Safety: go away if CTools is not at an appropriate version. + if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + return array(); + } + + $items['admin/build/panels/settings/panel-node'] = array( + 'title' => 'Panel nodes', + 'description' => 'Configure which content is available to add to panel node displays.', + 'access arguments' => array('administer panel-nodes'), + 'page callback' => 'panels_node_settings', + 'type' => MENU_LOCAL_TASK, + ); + + // Avoid some repetition on these: + $base = array( + 'access callback' => 'panels_node_edit_node', + 'access arguments' => array(1), + 'page arguments' => array(1), + 'type' => MENU_LOCAL_TASK, + ); + + $items['node/%node/panel_layout'] = array( + 'title' => 'Panel layout', + 'page callback' => 'panels_node_edit_layout', + 'weight' => 2, + ) + $base; + + $items['node/%node/panel_content'] = array( + 'title' => 'Panel content', + 'page callback' => 'panels_node_edit_content', + 'weight' => 3, + ) + $base; + + $items['node/add/panel/choose-layout'] = array( + 'title' => 'Choose layout', + 'access arguments' => array('create panel-nodes'), + 'page callback' => 'panels_node_add', + 'type' => MENU_CALLBACK, + ); + + return $items; +} + +function panels_node_edit_node($node) { + if (!isset($node->panels_node)) { + return FALSE; + } + + return node_access('update', $node); +} + +// --------------------------------------------------------------------------- +// Node hooks + +/** + * Implementation of hook_node_info(). + */ +function panels_node_node_info() { + // Safety: go away if CTools is not at an appropriate version. + if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { + return array(); + } + + return array( + 'panel' => array( + 'name' => t('Panel'), + 'module' => 'panels_node', + 'body_label' => t('Teaser'), + 'description' => t("A panel layout broken up into rows and columns."), + ), + ); +} + +/** + * Implementation of hook_access(). + */ +function panels_node_access($op, $node, $account) { + if (user_access('administer panel-nodes', $account)) { + return TRUE; + } + + if ($op == 'create' && user_access('create panel-nodes', $account)) { + return TRUE; + } + + if ($op == 'update' && (user_access('edit any panel-nodes', $account) || $node->uid == $account->uid && user_access('edit own panel-nodes', $account))) { + return TRUE; + } + + + if ($op == 'delete' && (user_access('delete any panel-nodes') || $node->uid == $account->uid && user_access('delete own panel-nodes'))) { + return TRUE; + } +} + +function panels_node_add() { + $output = ''; + + ctools_include('plugins', 'panels'); + ctools_include('common', 'panels'); + + $layouts = panels_common_get_allowed_layouts('panels_node'); + return panels_common_print_layout_links($layouts, 'node/add/panel', array('query' => $_GET)); +} + +/** + * Implementation of hook_form(). + */ +function panels_node_form(&$node, &$param) { + ctools_include('plugins', 'panels'); + + $form['panels_node']['#tree'] = TRUE; + if (empty($node->nid) && arg(0) == 'node' && arg(1) == 'add') { + // Grab our selected layout from the $node, If it doesn't exist, try arg(3) + // and if that doesn't work present them with a list to pick from. + $panel_layout = isset($node->panel_layout) ? $node->panel_layout : arg(3); + if (empty($panel_layout)) { + $opts = $_GET; + unset($opts['q']); + return drupal_goto('node/add/panel/choose-layout', $opts); + } + + $layout = panels_get_layout($panel_layout); + if (empty($layout)) { + return drupal_not_found(); + } + $form['panels_node']['layout'] = array( + '#type' => 'value', + '#value' => $panel_layout, + ); + } + + $type = node_get_types('type', $node); + + $form['title'] = array( + '#type' => 'textfield', + '#title' => check_plain($type->title_label), + '#required' => TRUE, + '#default_value' => $node->title, + ); + + if (!empty($type->body_label)) { + $form['body_field']['#prefix'] = '<div class="body-field-wrapper">'; + $form['body_field']['#suffix'] = '</div>'; + $form['body_field']['body'] = array( + '#type' => 'textarea', + '#title' => check_plain($type->body_label), + '#rows' => 10, + '#required' => TRUE, + '#description' => t('The teaser is a piece of text to describe when the panel is listed (such as when promoted to front page); the actual content will only be displayed on the full node view.'), + '#default_value' => $node->body, + ); + $form['body_field']['format'] = filter_form($node->format); // Now we can set the format! + } + +// drupal_set_message('<pre>' . check_plain(var_export($node, true)) . '</pre>'); + $css_id = ''; + if (!empty($node->panels_node['css_id'])) { + $css_id = $node->panels_node['css_id']; + } + + $form['panels_node']['css_id'] = array( + '#type' => 'textfield', + '#title' => t('CSS ID'), + '#size' => 30, + '#description' => t('An ID that can be used by CSS to style the panel.'), + '#default_value' => $css_id, + ); + + // Support for different rendering pipelines + // Mostly borrowed from panel_context.inc + $pipelines = panels_get_renderer_pipelines(); + + // If there are no pipelines, that probably means we're operating in + // legacy mode. + if (empty($pipelines)) { + // We retain the original pipeline so we don't wreck things by installing + // old modules. + $form['panels_node']['pipeline'] = array( + '#type' => 'value', + '#value' => $node->panels_node['pipeline'], + ); + } + else { + $options = array(); + foreach ($pipelines as $name => $pipeline) { + $options[$name] = check_plain($pipeline->admin_title) . '<div class="description">' . check_plain($pipeline->admin_description) . '</div>'; + } + + $form['panels_node']['pipeline'] = array( + '#type' => 'radios', + '#options' => $options, + '#title' => t('Renderer'), + '#default_value' => !empty($node->panels_node['pipeline']) ? $node->panels_node['pipeline'] : 'standard', + ); + } + + return $form; +} + +/** + * Implementation of hook_validate(). + */ +function panels_node_validate($node) { + if (!$node->nid && empty($node->panels_node['layout'])) { + form_set_error('', t('Please select a layout.')); + } +} + +/** + * Implementation of hook_load(). + * + * Panels does not use revisions for nodes because that would open us up + * to have completely separate displays, and we'd have to copy them, + * and that's going to be a LOT of data. + */ +function panels_node_load($node) { + // We shortcut this because only in some really drastic corruption circumstance will this + // not work. + $additions['panels_node'] = db_fetch_array(db_query("SELECT * FROM {panels_node} WHERE nid = %d", $node->nid)); + return $additions; +} + +/** + * Implementation of hook_insert(). + */ +function panels_node_insert(&$node) { + // Create a new display and record that. + $display = panels_new_display(); + $display->layout = $node->panels_node['layout']; + + // Special handling for nodes being imported from an export.module data dump. + if (!empty($node->export_display)) { + // This works by overriding the $display set above + eval($node->export_display); + unset($node->export_display); + } + + panels_save_display($display); + $css_id = $node->panels_node['css_id']; + + db_query("INSERT INTO {panels_node} (nid, did, css_id, pipeline) VALUES (%d, %d, '%s', '%s')", $node->nid, $display->did, $node->panels_node['css_id'], $node->panels_node['pipeline']); + + $node->panels_node['did'] = $display->did; +} + +/** + * Implementation of hook_delete(). + */ +function panels_node_delete(&$node) { + db_query("DELETE FROM {panels_node} WHERE nid = %d", $node->nid); + if (!empty($node->panels_node['did'])) { + panels_delete_display($node->panels_node['did']); + } +} + +/** + * Implementation of hook_update(). + */ +function panels_node_update($node) { + db_query("UPDATE {panels_node} SET css_id = '%s', pipeline = '%s' WHERE nid = %d", $node->panels_node['css_id'], $node->panels_node['pipeline'], $node->nid); +} + +/** + * Implementation of hook_view(). + */ +function panels_node_view($node, $teaser = FALSE, $page = FALSE) { + static $rendering = array(); + + // Prevent loops if someone foolishly puts the node inside itself: + if (!empty($rendering[$node->nid])) { + return $node; + } + + $rendering[$node->nid] = TRUE; + ctools_include('plugins', 'panels'); + if ($teaser) { + // Do the standard view for teaser. + $node = node_prepare($node, $teaser); + // Because our teasier is never the same as our content, *always* provide + // the read more flag. + $node->readmore = TRUE; + } + else { + if (!empty($node->panels_node['did'])) { + $display = panels_load_display($node->panels_node['did']); + $display->css_id = $node->panels_node['css_id']; + // TODO: Find a way to make sure this can't node_view. + $display->context = panels_node_get_context($node); + $renderer = panels_get_renderer($node->panels_node['pipeline'], $display); + $node->content['body'] = array( + '#value' => panels_render_display($display, $renderer), + '#weight' => 0, + ); + } + } + + unset($rendering[$node->nid]); + return $node; +} + +// --------------------------------------------------------------------------- +// Administrative pages + +/** + * Settings for panel nodes. + */ +function panels_node_settings() { + ctools_include('common', 'panels'); + return drupal_get_form('panels_common_settings', 'panels_node'); +} + +// --------------------------------------------------------------------------- +// Meat of the Panels API; almost completely passing through to panels.module + +/** + * Pass through to the panels layout editor. + */ +function panels_node_edit_layout($node) { +// ctools_include('plugins', 'panels'); + ctools_include('context'); + $display = panels_load_display($node->panels_node['did']); + $display->context = panels_node_get_context($node); + return panels_edit_layout($display, t('Save'), "node/$node->nid/panel_layout", 'panels_node'); +} + +/** + * Pass through to the panels content editor. + */ +function panels_node_edit_content($node) { +// ctools_include('plugins', 'panels'); + ctools_include('context'); + $display = panels_load_display($node->panels_node['did']); + $display->context = panels_node_get_context($node); + ctools_include('common', 'panels'); + $content_types = panels_common_get_allowed_types('panels_node', $display->context); + + // Print this with theme('page') so that blocks are disabled while editing a display. + // This is important because negative margins in common block layouts (i.e, Garland) + // messes up the drag & drop. + print theme('page', panels_edit($display, "node/$node->nid/panel_content", $content_types), FALSE); +} + +/** + * Build the context to use for a panel node. + */ +function panels_node_get_context(&$node) { + ctools_include('context'); + $context = ctools_context_create('node', $node); + $context->identifier = t('This node'); + $context->keyword = 'node'; + return array('panel-node' => $context); +} + +/** + * Implementation of hook_export_node_alter() + * + * Integrate with export.module for saving panel_nodes into code. + */ +function panels_node_export_node_alter(&$node, $original_node, $method) { + if ($method == 'export') { + $node_export_omitted = variable_get('node_export_omitted', array()); + if (variable_get('node_export_method', '') != 'save-edit' && (array_key_exists('panel', $node_export_omitted) && !$node_export_omitted['panel'])) { + drupal_set_message(t("NOTE: in order to import panel_nodes you must first set the export.module settings to \"Save as a new node then edit\", otherwise it won't work.")); + } + $display = panels_load_display($node->panels_node['did']); + $export = panels_export_display($display); + $node->export_display = $export; + } +} + +/** + * Implementation of hook_panels_dashboard_blocks(). + * + * Adds panel nodes information to the Panels dashboard. + */ +function panels_node_panels_dashboard_blocks(&$vars) { + $vars['links']['panels_node'] = array( + 'title' => l(t('Panel node'), 'node/add/panel'), + 'description' => t('Panel nodes are node content and appear in your searches, but are more limited than panel pages.'), + 'weight' => -1, + ); +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/cache/simple.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/cache/simple.inc new file mode 100644 index 0000000000000000000000000000000000000000..916df4222e0c61f6d9d984870f9f265d05c716be --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/cache/simple.inc @@ -0,0 +1,137 @@ +<?php + +/** + * @file + * Provides a simple time-based caching option for panel panes. + */ + +// Plugin definition +$plugin = array( + 'title' => t("Simple cache"), + 'description' => t('Simple caching is a time-based cache. This is a hard limit, and once cached it will remain that way until the time limit expires.'), + 'cache get' => 'panels_simple_cache_get_cache', + 'cache set' => 'panels_simple_cache_set_cache', + 'cache clear' => 'panels_simple_cache_clear_cache', + 'settings form' => 'panels_simple_cache_settings_form', + 'settings form submit' => 'panels_simple_cache_settings_form_submit', + 'defaults' => array( + 'lifetime' => 15, + 'granularity' => 'none', + ), +); + +/** + * Get cached content. + */ +function panels_simple_cache_get_cache($conf, $display, $args, $contexts, $pane = NULL) { + $cid = panels_simple_cache_get_id($conf, $display, $args, $contexts, $pane); + $cache = cache_get($cid, 'cache'); + if (!$cache) { + return FALSE; + } + + if ((time() - $cache->created) > $conf['lifetime']) { + return FALSE; + } + + return $cache->data; +} + +/** + * Set cached content. + */ +function panels_simple_cache_set_cache($conf, $content, $display, $args, $contexts, $pane = NULL) { + $cid = panels_simple_cache_get_id($conf, $display, $args, $contexts, $pane); + cache_set($cid, $content); +} + +/** + * Clear cached content. + * + * Cache clears are always for an entire display, regardless of arguments. + */ +function panels_simple_cache_clear_cache($display) { + $cid = 'panels_simple_cache'; + + // This is used in case this is an in-code display, which means did will be something like 'new-1'. + if (isset($display->owner) && isset($display->owner->id)) { + $cid .= ':' . $display->owner->id; + } + $cid .= ':' . $display->did; + + cache_clear_all($cid, 'cache', TRUE); +} + +/** + * Figure out an id for our cache based upon input and settings. + */ +function panels_simple_cache_get_id($conf, $display, $args, $contexts, $pane) { + $id = 'panels_simple_cache'; + + // This is used in case this is an in-code display, which means did will be something like 'new-1'. + if (isset($display->owner) && isset($display->owner->id)) { + $id .= ':' . $display->owner->id; + } + $id .= ':' . $display->did; + + if ($pane) { + $id .= ':' . $pane->pid; + } + + if (user_access('view pane admin links')) { + $id .= ':admin'; + } + + switch ($conf['granularity']) { + case 'args': + foreach ($args as $arg) { + $id .= ':' . $arg; + } + break; + + case 'context': + if (!is_array($contexts)) { + $contexts = array($contexts); + } + foreach ($contexts as $context) { + if (isset($context->argument)) { + $id .= ':' . $context->argument; + } + } + } + if (module_exists('locale')) { + global $language; + $id .= ':' . $language->language; + } + + if($pane->configuration['use_pager'] == 1) { + $id .= ':p' . check_plain($_GET['page']); + } + + return $id; +} + +function panels_simple_cache_settings_form($conf, $display, $pid) { + $options = drupal_map_assoc(array(15, 30, 60, 120, 180, 240, 300, 600, 900, 1200, 1800, 3600, 7200, 14400, 28800, 43200, 86400, 172800, 259200, 345600, 604800), 'format_interval'); + $form['lifetime'] = array( + '#title' => t('Lifetime'), + '#type' => 'select', + '#options' => $options, + '#default_value' => $conf['lifetime'], + ); + + $form['granularity'] = array( + '#title' => t('Granularity'), + '#type' => 'select', + '#options' => array( + 'args' => t('Arguments'), + 'context' => t('Context'), + 'none' => t('None'), + ), + '#description' => t('If "arguments" are selected, this content will be cached per individual argument to the entire display; if "contexts" are selected, this content will be cached per unique context in the pane or display; if "neither" there will be only one cache for this pane.'), + '#default_value' => $conf['granularity'], + ); + + return $form; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/editor.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/editor.inc new file mode 100644 index 0000000000000000000000000000000000000000..501b7b8db37f498374c1abfeb7ec651f57f4063f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/editor.inc @@ -0,0 +1,8 @@ +<?php + +$plugin = array( + 'handler' => array( + 'class' => 'panels_renderer_editor', + 'parent' => 'standard', + ), +); \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/legacy.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/legacy.inc new file mode 100644 index 0000000000000000000000000000000000000000..2082105015c7af08519e7e57d4bbd58ae55dfe75 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/legacy.inc @@ -0,0 +1,7 @@ +<?php + +$plugin = array( + 'handler' => array( + 'class' => 'panels_renderer_legacy', + ), +); \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_editor.class.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_editor.class.php new file mode 100644 index 0000000000000000000000000000000000000000..0ca2146fe7848475131f6e39c82adfc70db30164 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_editor.class.php @@ -0,0 +1,1902 @@ +<?php + +/** + * @file + * Class file to control the main Panels editor. + */ + +class panels_renderer_editor extends panels_renderer_standard { + + /** + * An array of AJAX commands to return. If populated it will automatically + * be used by the AJAX router. + */ + var $commands = array(); + var $admin = TRUE; + // ------------------------------------------------------------------------- + // Display edit rendering. + + function edit() { + ctools_include('form'); + $form_state = array( + 'display' => &$this->display, + 'renderer' => &$this, + 'content_types' => $this->cache->content_types, + 're_render' => FALSE, + 'no_redirect' => TRUE, + 'display_title' => !empty($this->cache->display_title), + 'cache key' => $this->display->cache_key, + ); + + $output = ctools_build_form('panels_edit_display_form', $form_state); + if ($output) { + return $output; + } + + // no output == submit + if (!$output) { + if (!empty($form_state['clicked_button']['#save-display'])) { + drupal_set_message(t('Panel content has been updated.')); + panels_save_display($this->display); + } + else { + drupal_set_message(t('Your changes have been discarded.')); + } + + panels_cache_clear('display', $this->display->did); + return $this->display; + } + } + + function add_meta() { + parent::add_meta(); + if ($this->admin) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_modal_add_js(); + + ctools_add_js('panels-base', 'panels'); + ctools_add_js('display_editor', 'panels'); + ctools_add_css('panels_dnd', 'panels'); + ctools_add_css('panels_admin', 'panels'); + } + } + + function render() { + // Pass through to normal rendering if not in admin mode. + if (!$this->admin) { + return parent::render(); + } + + $this->add_meta(); + + $output = '<div class="panels-dnd" id="panels-dnd-main">'; + $output .= $this->render_layout(); + $output .= '</div>'; + + return $output; + } + + function render_region($region_id, $panes) { + // Pass through to normal rendering if not in admin mode. + if (!$this->admin) { + return parent::render_region($region_id, $panes); + } + + $content = implode('', $panes); + + $panel_buttons = $this->get_region_links($region_id); + + // @todo this should be panel-region not panels-display -- but CSS and .js has to be updated. + $output = "<div class='panels-display' id='panel-pane-$region_id'>"; + $output .= $panel_buttons; + $output .= "<h2 class='label'>" . check_plain($this->plugins['layout']['panels'][$region_id]) . "</h2>"; + $output .= $content; + $output .= "</div>"; + + return $output; + } + + function render_pane(&$pane) { + // Pass through to normal rendering if not in admin mode. + if (!$this->admin) { + return parent::render_pane($pane); + } + + ctools_include('content'); + $content_type = ctools_get_content_type($pane->type); + + // This is just used for the title bar of the pane, not the content itself. + // If we know the content type, use the appropriate title for that type, + // otherwise, set the title using the content itself. + $title = ctools_content_admin_title($content_type, $pane->subtype, $pane->configuration, $this->display->context); + if (!$title) { + $title = t('Deleted/missing content type @type', array('@type' => $pane->type)); + } + + $buttons = $this->get_pane_links($pane, $content_type); + + // Render administrative buttons for the pane. + + $block = new stdClass(); + if (empty($content_type)) { + $block->title = '<em>' . t('Missing content type') . '</em>'; + $block->content = t('This pane\'s content type is either missing or has been deleted. This pane will not render.'); + } + else { + $block = ctools_content_admin_info($content_type, $pane->subtype, $pane->configuration, $this->display->context); + } + + $output = ''; + $class = 'panel-pane'; + + if (empty($pane->shown)) { + $class .= ' hidden-pane'; + } + + if (isset($this->display->title_pane) && $this->display->title_pane == $pane->pid) { + $class .= ' panel-pane-is-title'; + } + + $output = '<div class="' . $class . '" id="panel-pane-' . $pane->pid . '">'; + + if (!$block->title) { + $block->title = t('No title'); + } + + $output .= '<div class="grabber">'; + if ($buttons) { + $output .= '<span class="buttons">' . $buttons . '</span>'; + } + $output .= '<span class="text">' . $title . '</span>'; + $output .= '</div>'; // grabber + + $output .= '<div class="panel-pane-collapsible">'; + $output .= '<div class="pane-title">' . $block->title . '</div>'; + $output .= '<div class="pane-content">' . filter_xss_admin($block->content) . '</div>'; + $output .= '</div>'; // panel-pane-collapsible + + $output .= '</div>'; // panel-pane + + return $output; + } + + /** + * Get the style links. + * + * This is abstracted out since we have styles on both panes and regions. + */ + function get_style_links($type, $id = NULL) { + $info = $this->get_style($type, $id); + $style = $info[0]; + $conf = $info[1]; + + $style_title = isset($style['title']) ? $style['title'] : t('Default'); + + $style_links[] = array( + 'title' => $style_title, + 'attributes' => array('class' => 'panels-text'), + ); + + $style_links[] = array( + 'title' => t('Change'), + 'href' => $this->get_url('style-type', $type, $id), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + + $function = $type != 'pane' ? 'settings form' : 'pane settings form'; + if (panels_plugin_get_function('styles', $style, $function)) { + $style_links[] = array( + 'title' => t('Settings'), + 'href' => $this->get_url('style-settings', $type, $id), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + } + + return $style_links; + } + + /** + * Get the links for a panel display. + * + * This is abstracted out for easy ajax replacement. + */ + function get_display_links() { + $links = array(); + + if (user_access('administer panels styles')) { + $style_links = $this->get_style_links('display'); + + $links[] = array( + 'title' => '<span class="dropdown-header">' . t('Style') . '</span>' . theme_links($style_links), + 'html' => TRUE, + 'attributes' => array('class' => 'panels-sub-menu'), + ); + } + + if (user_access('use panels caching features')) { + $links[] = array( + 'title' => '<hr />', + 'html' => TRUE, + ); + + $method = isset($this->display->cache['method']) ? $this->display->cache['method'] : 0; + $info = panels_get_cache($method); + $cache_method = isset($info['title']) ? $info['title'] : t('No caching'); + + $cache_links[] = array( + 'title' => $cache_method, + 'attributes' => array('class' => 'panels-text'), + ); + $cache_links[] = array( + 'title' => t('Change'), + 'href' => $this->get_url('cache-method', 'display'), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + if (panels_plugin_get_function('cache', $info, 'settings form')) { + $cache_links[] = array( + 'title' => t('Settings'), + 'href' => $this->get_url('cache-settings', 'display'), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + } + + $links[] = array( + 'title' => '<span class="dropdown-header">' . t('Caching') . '</span>' . theme_links($cache_links), + 'html' => TRUE, + 'attributes' => array('class' => 'panels-sub-menu'), + ); + } + + return theme('ctools_dropdown', t('Display settings'), $links, FALSE, 'panels-display-links'); + } + + /** + * Render the links to display when editing a region. + */ + function get_region_links($region_id) { + $links = array(); + $links[] = array( + 'title' => t('Add content'), + 'href' => $this->get_url('select-content', $region_id), + 'attributes' => array( + 'class' => 'ctools-use-modal', + ), + ); + + if (user_access('administer panels styles')) { + $links[] = array( + 'title' => '<hr />', + 'html' => TRUE, + ); + + $style_links = $this->get_style_links('region', $region_id); + + $links[] = array( + 'title' => '<span class="dropdown-header">' . t('Style') . '</span>' . theme_links($style_links), + 'html' => TRUE, + 'attributes' => array('class' => 'panels-sub-menu'), + ); + } + + return theme('ctools_dropdown', theme('image', ctools_image_path('icon-addcontent.png', 'panels')), $links, TRUE, 'pane-add-link panels-region-links-' . $region_id); + } + + /** + * Render the links to display when editing a pane. + */ + function get_pane_links($pane, $content_type) { + $links = array(); + + if (!empty($pane->shown)) { + $links[] = array( + 'title' => t('Disable this pane'), + 'href' => $this->get_url('hide', $pane->pid), + 'attributes' => array('class' => 'ctools-use-ajax'), + ); + } + else { + $links[] = array( + 'title' => t('Enable this pane'), + 'href' => $this->get_url('show', $pane->pid), + 'attributes' => array('class' => 'ctools-use-ajax'), + ); + } + + if (isset($this->display->title_pane) && $this->display->title_pane == $pane->pid) { + $links['panels-set-title'] = array( + 'title' => t('✓Panel title'), + 'html' => TRUE, + ); + } + else { + $links['panels-set-title'] = array( + 'title' => t('Panel title'), + 'href' => $this->get_url('panel-title', $pane->pid), + 'attributes' => array('class' => 'ctools-use-ajax'), + ); + } + + $subtype = ctools_content_get_subtype($content_type, $pane->subtype); + + if (ctools_content_editable($content_type, $subtype, $pane->configuration)) { + $links[] = array( + 'title' => isset($content_type['edit text']) ? $content_type['edit text'] : t('Settings'), + 'href' => $this->get_url('edit-pane', $pane->pid), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + } + + if (user_access('administer advanced pane settings')) { + $links[] = array( + 'title' => t('CSS properties'), + 'href' => $this->get_url('pane-css', $pane->pid), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + } + + if (user_access('administer panels styles')) { + $links[] = array( + 'title' => '<hr />', + 'html' => TRUE, + ); + + $style_links = $this->get_style_links('pane', $pane->pid); + + $links[] = array( + 'title' => '<span class="dropdown-header">' . t('Style') . '</span>' . theme_links($style_links), + 'html' => TRUE, + 'attributes' => array('class' => 'panels-sub-menu'), + ); + } + + if (user_access('administer pane access')) { + $links[] = array( + 'title' => '<hr />', + 'html' => TRUE, + ); + + $contexts = $this->display->context; + // Make sure we have the logged in user context + if (!isset($contexts['logged-in-user'])) { + $contexts['logged-in-user'] = ctools_access_get_loggedin_context(); + } + + $visibility_links = array(); + + if (!empty($pane->access['plugins'])) { + foreach ($pane->access['plugins'] as $id => $test) { + $plugin = ctools_get_access_plugin($test['name']); + $access_title = isset($plugin['title']) ? $plugin['title'] : t('Broken/missing access plugin %plugin', array('%plugin' => $test['name'])); + $access_description = ctools_access_summary($plugin, $contexts, $test); + + $visibility_links[] = array( + 'title' => $access_description, + 'href' => $this->get_url('access-configure-test', $pane->pid, $id), + 'attributes' => array('class' => 'ctools-use-modal panels-italic'), + ); + } + } + if (empty($visibility_links)) { + $visibility_links[] = array( + 'title' => t('No rules'), + 'attributes' => array('class' => 'panels-text'), + ); + } + + $visibility_links[] = array( + 'title' => t('Add new rule'), + 'href' => $this->get_url('access-add-test', $pane->pid), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + + $visibility_links[] = array( + 'title' => t('Settings'), + 'href' => $this->get_url('access-settings', $pane->pid), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + + $links[] = array( + 'title' => '<span class="dropdown-header">' . t('Visibility rules') . '</span>' . theme_links($visibility_links), + 'html' => TRUE, + 'attributes' => array('class' => 'panels-sub-menu'), + ); + } + + if (panels_get_caches() && user_access('use panels caching features')) { + $links[] = array( + 'title' => '<hr />', + 'html' => TRUE, + ); + + $method = isset($pane->cache['method']) ? $pane->cache['method'] : 0; + $info = panels_get_cache($method); + $cache_method = isset($info['title']) ? $info['title'] : t('No caching'); + $cache_links[] = array( + 'title' => $cache_method, + 'attributes' => array('class' => 'panels-text'), + ); + $cache_links[] = array( + 'title' => t('Change'), + 'href' => $this->get_url('cache-method', $pane->pid), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + if (panels_plugin_get_function('cache', $info, 'settings form')) { + $cache_links[] = array( + 'title' => t('Settings'), + 'href' => $this->get_url('cache-settings', $pane->pid), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + } + + $links[] = array( + 'title' => '<span class="dropdown-header">' . t('Caching') . '</span>' . theme_links($cache_links), + 'html' => TRUE, + 'attributes' => array('class' => 'panels-sub-menu'), + ); + } + + $links[] = array( + 'title' => '<hr />', + 'html' => TRUE, + ); + + $links[] = array( + 'title' => t('Remove'), + 'href' => '#', + 'attributes' => array( + 'class' => 'pane-delete', + 'id' => "pane-delete-panel-pane-$pane->pid", + ), + ); + + return theme('ctools_dropdown', theme('image', ctools_image_path('icon-configure.png', 'panels')), $links, TRUE); + } + + // ----------------------------------------------------------------------- + // Display edit AJAX callbacks and helpers. + + /** + * Generate a URL path for the AJAX editor. + */ + function get_url() { + $args = func_get_args(); + $command = array_shift($args); + $url = 'panels/ajax/' . $this->plugin['name'] . '/' . $command . '/' . $this->display->cache_key; + if ($args) { + $url .= '/' . implode('/', $args); + } + + return $url; + } + + /** + * AJAX command to show a pane. + */ + function ajax_show($pid = NULL) { + if (empty($this->display->content[$pid])) { + ctools_ajax_render_error(t('Invalid pane id.')); + } + + $this->display->content[$pid]->shown = TRUE; + panels_edit_cache_set($this->cache); + + $this->command_update_pane($pid); + } + + /** + * AJAX command to show a pane. + */ + function ajax_hide($pid = NULL) { + if (empty($this->display->content[$pid])) { + ctools_ajax_render_error(t('Invalid pane id.')); + } + + $this->display->content[$pid]->shown = FALSE; + panels_edit_cache_set($this->cache); + + $this->command_update_pane($pid); + } + + /** + * AJAX command to present a dialog with a list of available content. + */ + function ajax_select_content($region = NULL, $category = NULL) { + if (!array_key_exists($region, $this->plugins['layout']['panels'])) { + ctools_modal_render(t('Error'), t('Invalid input')); + } + + $title = t('Add content to !s', array('!s' => $this->plugins['layout']['panels'][$region])); + + $categories = $this->get_categories($this->cache->content_types); + + if (empty($categories)) { + $output = t('There are no content types you may add to this display.'); + } + else { + $output = '<div class="panels-add-content-modal">'; + $selector = $this->render_category_selector($categories, $category, $region); + + $content = !empty($categories[$category]['content']) ? $categories[$category]['content'] : array(); + $center = $this->render_category($content, $category, $region); + + $output .= '<div class="panels-section-column panels-section-column-categories">' + . '<div class="inside">' . $selector . '</div></div>'; + $output .= $center; + $output .= '</div>'; // panels-add-content-modal + } + + $this->commands[] = ctools_modal_command_display($title, $output); + } + + /** + * Return the category name and the category key of a given content + * type. + * + * @todo -- this should be in CTools. + */ + function get_category($content_type) { + if (isset($content_type['top level'])) { + $category = 'root'; + } + else if (isset($content_type['category'])) { + if (is_array($content_type['category'])) { + list($category, $weight) = $content_type['category']; + } + else { + $category = $content_type['category']; + } + } + else { + $category = t('Uncategorized'); + } + + return array(preg_replace('/[^a-z0-9]/', '-', strtolower($category)), $category); + } + + + /** + * Create a list of categories from all of the content type. + * + * @return array + * An array of categories. Each entry in the array will also be an array + * with 'title' as the printable title of the category, and 'content' + * being an array of all content in the category. Each item in the 'content' + * array contain the array plugin definition so that it can be later + * found in the content array. They will be keyed by the title so that they + * can be sorted. + */ + function get_categories($content_types) { + $categories = array(); + $category_names = array(); + + foreach ($content_types as $type_name => $subtypes) { + foreach ($subtypes as $subtype_name => $content_type) { + list($category_key, $category) = $this->get_category($content_type); + + if (empty($categories[$category_key])) { + $categories[$category_key] = array( + 'title' => $category, + 'content' => array(), + ); + $category_names[$category_key] = $category; + } + + $content_title = filter_xss_admin($content_type['title']); + + // Ensure content with the same title doesn't overwrite each other. + while (isset($categories[$category_key]['content'][$content_title])) { + $content_title .= '-'; + } + + $categories[$category_key]['content'][$content_title] = $content_type; + $categories[$category_key]['content'][$content_title]['type_name'] = $type_name; + $categories[$category_key]['content'][$content_title]['subtype_name'] = $subtype_name; + } + } + + // Now sort + natcasesort($category_names); + foreach ($category_names as $category => $name) { + $output[$category] = $categories[$category]; + } + + return $output; + } + + /** + * Render a single link to add a content type. + */ + function render_add_content_link($region, $content_type) { + $title = filter_xss_admin($content_type['title']); + $description = isset($content_type['description']) ? $content_type['description'] : $title; + $icon = ctools_content_admin_icon($content_type); + $url = $this->get_url('add-pane', $region, $content_type['type_name'], $content_type['subtype_name']); + + $output = '<div class="content-type-button clear-block">'; + $output .= ctools_ajax_image_button($icon, $url, $description, 'panels-modal-add-config'); + $output .= '<div>' . ctools_ajax_text_button($title, $url, $description, 'panels-modal-add-config') . '</div>'; + $output .= '</div>'; + + return $output; + } + + /** + * Render the selector widget in the add content modal to select categories. + */ + function render_category_selector($categories, $category, $region) { + $output = '<div class="panels-categories-box">'; + + // Render our list of categories in column 0. + foreach ($categories as $key => $category_info) { + if ($key == 'root') { + continue; + } + + $class = 'panels-modal-add-category'; + if ($key == $category) { + $class .= ' active'; + } + + $url = $this->get_url('select-content', $region, $key); + $output .= ctools_ajax_text_button($category_info['title'], $url, '', $class); + } + + $output .= '</div>'; // panels-categories-box + + if (!empty($categories['root'])) { + foreach ($categories['root']['content'] as $content_type) { + $output .= $this->render_add_content_link($region, $content_type); + } + } + + return $output; + } + + /** + * Render all of the content links in a category. + */ + function render_category($content, $category, $region) { + if (empty($category) || empty($content) || $category == 'root') { + $output = '<div class="panels-categories-description">'; + $output .= t('Content options are divided by category. Please select a category from the left to proceed.'); + $output .= '</div>'; + } + else { + $titles = array_keys($content); + natcasesort($titles); + + // Fill out the info for our current category. + $columns = 2; + $col[1] = ''; + $col[2] = ''; + + $col_size = count($titles) / $columns; + $count = 0; + foreach ($titles as $title) { + $which = floor($count++ / $col_size) + 1; // we leave 0 for the categories. + $col[$which] .= $this->render_add_content_link($region, $content[$title]); + } + + $output = '<div class="panels-section-columns">'; + foreach ($col as $id => $column) { + $output .= '<div class="panels-section-column panels-section-column-' . $id . '">' + . '<div class="inside">' . $column . '</div></div>'; + } + $output .= '</div>'; // columns + } + + if ($messages = theme('status_messages')) { + $output = '<div class="messages">' . $messages . '</div>' . $output; + } + return $output; + } + + /** + * AJAX entry point to add a new pane. + */ + function ajax_add_pane($region = NULL, $type_name = NULL, $subtype_name = NULL, $step = NULL) { + $content_type = ctools_get_content_type($type_name); + $subtype = ctools_content_get_subtype($content_type, $subtype_name); + + if (!isset($step) || !isset($this->cache->new_pane)) { + $pane = panels_new_pane($type_name, $subtype_name, TRUE); + $this->cache->new_pane = &$pane; + } + else { + $pane = &$this->cache->new_pane; + } + + $form_state = array( + 'display' => &$this->cache->display, + 'contexts' => $this->cache->display->context, + 'pane' => &$pane, + 'cache_key' => $this->display->cache_key, + 'cache' => &$this->cache, + 'ajax' => TRUE, + 'modal' => TRUE, + // This will force the system to not automatically render. + 'modal return' => TRUE, + 'commands' => array(), + ); + + $form_info = array( + 'path' => $this->get_url('add-pane', $region, $type_name, $subtype_name, '%step'), + 'show cancel' => TRUE, + 'next callback' => 'panels_ajax_edit_pane_next', + 'finish callback' => 'panels_ajax_edit_pane_finish', + 'cancel callback' => 'panels_ajax_edit_pane_cancel', + ); + + $output = ctools_content_form('add', $form_info, $form_state, $content_type, $pane->subtype, $subtype, $pane->configuration, $step); + + // If $rc is FALSE, there was no actual form. + if ($output === FALSE || !empty($form_state['complete'])) { + $pane = $this->cache->new_pane; + unset($this->cache->new_pane); + + // Add the pane to the display + $this->display->add_pane($pane, $region); + panels_edit_cache_set($this->cache); + + // Tell the client to draw the pane + $this->command_add_pane($pane); + + // Dismiss the modal. + $this->commands[] = ctools_modal_command_dismiss(); + } + else if (!empty($form_state['cancel'])) { + // If cancelling, return to the activity. + list($category_key, $category) = $this->get_category($subtype); + $this->ajax_select_content($region, $category_key); + } + else { + // This overwrites any previous commands. + $this->commands = ctools_modal_form_render($form_state, $output); + } + } + + /** + * AJAX entry point to edit a pane. + */ + function ajax_edit_pane($pid = NULL, $step = NULL) { + if (empty($this->cache->display->content[$pid])) { + ctools_modal_render(t('Error'), t('Invalid pane id.')); + } + + $pane = &$this->cache->display->content[$pid]; + + $content_type = ctools_get_content_type($pane->type); + $subtype = ctools_content_get_subtype($content_type, $pane->subtype); + + $form_state = array( + 'display' => &$this->cache->display, + 'contexts' => $this->cache->display->context, + 'pane' => &$pane, + 'cache' => &$this->cache, + 'ajax' => TRUE, + 'modal' => TRUE, + 'modal return' => TRUE, + 'commands' => array(), + ); + + $form_info = array( + 'path' => $this->get_url('edit-pane', $pid, '%step'), + 'show cancel' => TRUE, + 'next callback' => 'panels_ajax_edit_pane_next', + 'finish callback' => 'panels_ajax_edit_pane_finish', + 'cancel callback' => 'panels_ajax_edit_pane_cancel', + ); + + $output = ctools_content_form('edit', $form_info, $form_state, $content_type, $pane->subtype, $subtype, $pane->configuration, $step); + + // If $rc is FALSE, there was no actual form. + if ($output === FALSE || !empty($form_state['cancel'])) { + // Dismiss the modal. + $this->commands[] = ctools_modal_command_dismiss(); + } + else if (!empty($form_state['complete'])) { + panels_edit_cache_set($this->cache); + $this->command_update_pane($pid); + $this->commands[] = ctools_modal_command_dismiss(); + } + else { + // This overwrites any previous commands. + $this->commands = ctools_modal_form_render($form_state, $output); + } + } + + /** + * AJAX entry point to select which pane is currently the title. + * + * @param string $pid + * The pane id for the pane object whose title state we're setting. + */ + function ajax_panel_title($pid = NULL) { + if (empty($this->display->content[$pid])) { + ctools_ajax_render_error(t('Invalid pane id.')); + } + + $pane = &$this->display->content[$pid]; + + $old_title = !empty($this->display->title_pane) ? $this->display->title_pane : NULL; + $this->display->title_pane = $pid; + + panels_edit_cache_set($this->cache); + + $this->command_update_pane($pane); + + if ($old_title && !empty($this->cache->display->content[$old_title])) { + $this->command_update_pane($this->cache->display->content[$old_title]); + } + } + + /** + * AJAX entry point to configure the cache method for a pane or the display. + * + * @param string $pid + * Either a pane id for a pane in the display, or 'display' to edit the + * display cache settings. + */ + function ajax_cache_method($pid = NULL) { + ctools_include('content'); + // This lets us choose whether we're doing the display's cache or + // a pane's. + if ($pid == 'display') { + $conf = &$this->display->cache; + $title = t('Cache method for this display'); + } + else if (!empty($this->display->content[$pid])) { + $pane = &$this->display->content[$pid]; + $subtype = ctools_content_get_subtype($pane->type, $pane->subtype); + $conf = &$pane->cache; + $title = t('Cache method for !subtype_title', array('!subtype_title' => $subtype['title'])); + } + else { + ctools_modal_render(t('Error'), t('Invalid pane id.')); + } + + $form_state = array( + 'display' => &$this->display, + 'conf' => &$conf, + 'title' => $title, + 'ajax' => TRUE, + ); + + $output = ctools_modal_form_wrapper('panels_edit_cache_method_form', $form_state); + if (!empty($output)) { + $this->commands = $output; + return; + } + + // Preserve this; this way we don't actually change the method until they + // have saved the form. + $info = panels_get_cache($form_state['method']); + $function = panels_plugin_get_function('cache', $info, 'settings form'); + if (!$function) { + $conf['method'] = $form_state['method']; + $conf['settings'] = array(); + panels_edit_cache_set($this->cache); + + $this->commands[] = ctools_modal_command_dismiss(); + + if ($pid != 'display') { + $this->command_update_pane($pane); + } + else { + $this->command_update_display_links(); + } + } + else { + $this->cache->method = $form_state['method']; + panels_edit_cache_set($this->cache); + // send them to next form. + return $this->ajax_cache_settings($pid); + } + } + + /** + * AJAX entry point to configure the cache settings for a pane or the display. + * + * @param string $pid + * Either a pane id for a pane in the display, or 'display' to edit the + * display cache settings. + */ + function ajax_cache_settings($pid = 0) { + ctools_include('content'); + + // This lets us choose whether we're doing the display's cache or + // a pane's. + if ($pid == 'display') { + $conf = &$this->display->cache; + $title = t('Cache settings for this display'); + } + else if (!empty($this->display->content[$pid])) { + $pane = &$this->display->content[$pid]; + $subtype = ctools_content_get_subtype($pane->type, $pane->subtype); + + $conf = &$pane->cache; + $title = t('Cache settings for !subtype_title', array('!subtype_title' => $subtype['title'])); + } + else { + ctools_modal_render(t('Error'), t('Invalid pane id.')); + } + + if (isset($this->cache->method) && (empty($conf['method']) || $conf['method'] != $this->cache->method)) { + $conf['method'] = $this->cache->method; + $info = panels_get_cache($conf['method']); + $conf['settings'] = isset($info['defaults']) ? $info['defaults'] : array(); + } + + $form_state = array( + 'display' => &$this->display, + 'pid' => $pid, + 'conf' => &$conf, + 'ajax' => TRUE, + 'title' => $title, + 'url' => url($this->get_url('cache-settings', $pid), array('absolute' => TRUE)), + ); + + $output = ctools_modal_form_wrapper('panels_edit_cache_settings_form', $form_state); + if (!empty($output)) { + $this->commands = $output; + return; + } + + panels_edit_cache_set($this->cache); + + $this->commands[] = ctools_modal_command_dismiss(); + + if ($pid != 'display') { + $this->command_update_pane($pane); + } + else { + $this->command_update_display_links(); + } + } + + /** + * AJAX entry point to select the style for a display, region or pane. + * + * @param string $type + * Either display, region or pane + * @param $pid + * The pane id, if a pane. The region id, if a region. + */ + function ajax_style_type($type, $pid = NULL) { + // This lets us choose whether we're doing the display's cache or + // a pane's. + switch ($type) { + case 'display': + $style = isset($this->display->panel_settings['style']) ? $this->display->panel_settings['style'] : 'default'; + $title = t('Default style for this display'); + break; + + case 'region': + $style = isset($this->display->panel_settings[$pid]['style']) ? $this->display->panel_settings[$pid]['style'] : '-1'; // -1 signifies to use the default setting. + $title = t('Panel style for region "!region"', array('!region' => $this->plugins['layout']['panels'][$pid])); + break; + + case 'pane': + ctools_include('content'); + $pane = &$this->display->content[$pid]; + $style = isset($pane->style['style']) ? $pane->style['style'] : 'default'; + $subtype = ctools_content_get_subtype($pane->type, $pane->subtype); + $title = t('Pane style for "!pane"', array('!pane' => $subtype['title'])); + break; + + default: + ctools_modal_render(t('Error'), t('Invalid pane id.')); + } + $info = $this->get_style($type, $pid); + $style_plugin = $info[0]; + $style_settings = $info[1]; + + // Backward compatibility: Translate old-style stylizer to new style + // stylizer. + if ($style == 'stylizer' && !empty($style_settings['style']) && $style_settings['style'] != '$') { + $style = 'stylizer:' . $style_settings['style']; + } + + $form_state = array( + 'display' => &$this->display, + 'style' => $style, + 'title' => $title, + 'ajax' => TRUE, + 'type' => $type, + ); + + $output = ctools_modal_form_wrapper('panels_edit_style_type_form', $form_state); + if (!empty($output)) { + $this->commands = $output; + return; + } + + // Preserve this; this way we don't actually change the method until they + // have saved the form. + $style = panels_get_style($form_state['style']); + $function = panels_plugin_get_function('styles', $style, ($type == 'pane') ? 'pane settings form' : 'settings form'); + if (!$function) { + if (isset($this->cache->style)) { + unset($this->cache->style); + } + + // If there's no settings form, just change the style and exit. + switch($type) { + case 'display': + $this->display->panel_settings['style'] = $form_state['style']; + if (isset($this->display->panel_settings['style_settings']['default'])) { + unset($this->display->panel_settings['style_settings']['default']); + } + break; + + case 'region': + $this->display->panel_settings[$pid]['style'] = $form_state['style']; + if (isset($this->display->panel_settings['style_settings'][$pid])) { + unset($this->display->panel_settings['style_settings'][$pid]); + } + break; + + case 'pane': + $pane->style['style'] = $form_state['style']; + if (isset($pane->style['settings'])) { + unset($pane->style['settings']); + } + + break; + } + panels_edit_cache_set($this->cache); + + $this->commands[] = ctools_modal_command_dismiss(); + + if ($type == 'pane') { + $this->command_update_pane($pane); + } + else if ($type == 'region') { + $this->command_update_region_links($pid); + } + else { + $this->command_update_display_links(); + } + } + else { + if ($form_state['style'] != $form_state['old_style']) { + $this->cache->style = $form_state['style']; + panels_edit_cache_set($this->cache); + } + + // send them to next form. + return $this->ajax_style_settings($type, $pid); + } + } + + /** + * Get the appropriate style from the panel in the cache. + * + * Since we have styles for regions, panes and the display itself, and + * they are stored differently, we use this method to simplify getting + * style information into a way that's easy to cope with. + */ + function get_style($type, $pid = '') { + if (isset($this->cache->style)) { + $style = panels_get_style($this->cache->style); + $defaults = isset($style['defaults']) ? $style['defaults'] : array(); + // Get the &$conf variable based upon whose style we're editing. + switch ($type) { + case 'display': + $this->display->panel_settings['style'] = $this->cache->style; + $this->display->panel_settings['style_settings']['default'] = $defaults; + break; + + case 'region': + $this->display->panel_settings[$pid]['style'] = $this->cache->style; + $this->display->panel_settings['style_settings'][$pid] = $defaults; + break; + + case 'pane': + $pane = &$this->display->content[$pid]; + $pane->style['style'] = $this->cache->style; + $pane->style['settings'] = $defaults; + $conf = &$pane->style['settings']; + break; + } + } + else { + switch ($type) { + case 'display': + $style = panels_get_style((!empty($this->display->panel_settings['style'])) ? $this->display->panel_settings['style'] : 'default'); + break; + + case 'region': + $style = panels_get_style((!empty($this->display->panel_settings[$pid]['style'])) ? $this->display->panel_settings[$pid]['style'] : '-1'); + break; + + case 'pane': + $pane = &$this->display->content[$pid]; + $style = panels_get_style(!empty($pane->style['style']) ? $pane->style['style'] : 'default'); + break; + } + } + + // Set up our $conf reference. + switch ($type) { + case 'display': + $conf = &$this->display->panel_settings['style_settings']['default']; + break; + + case 'region': + $conf = &$this->display->panel_settings['style_settings'][$pid]; + break; + + case 'pane': + ctools_include('content'); + $pane = &$this->display->content[$pid]; + $conf = &$pane->style['settings']; + break; + } + + // Backward compatibility: Translate old-style stylizer to new style + // stylizer. + if ($style['name'] == 'stylizer' && !empty($conf['style']) && $conf['style'] != '$') { + $style = panels_get_style('stylizer:' . $conf['style']); + } + + return array($style, &$conf); + } + + /** + * AJAX entry point to configure the style for a display, region or pane. + * + * @param string $type + * Either display, region or pane + * @param $pid + * The pane id, if a pane. The region id, if a region. + */ + function ajax_style_settings($type, $pid = '') { + $info = $this->get_style($type, $pid); + $style = $info[0]; + $conf = &$info[1]; + + switch ($type) { + case 'display': + $title = t('Style settings for @style (display)', array('@style' => $style['title'])); + break; + + case 'region': + $title = t('Style settings for style @style (Region "!region")', array('@style' => $style['title'], '!region' => $this->plugins['layout']['panels'][$pid])); + break; + + case 'pane': + ctools_include('content'); + $pane = &$this->display->content[$pid]; + $subtype = ctools_content_get_subtype($pane->type, $pane->subtype); + $title = t('Style settings for style @style (Pane "!pane")', array('@style' => $style['title'], '!pane' => $subtype['title'])); + break; + } + + $form_state = array( + 'display' => &$this->display, + 'type' => $type, + 'pid' => $pid, + 'conf' => &$conf, + 'style' => $style, + 'ajax' => TRUE, + 'title' => $title, + 'url' => url($this->get_url('style-settings', $type, $pid), array('absolute' => TRUE)), + 'renderer' => &$this, + ); + + $output = ctools_modal_form_wrapper('panels_edit_style_settings_form', $form_state); + if (!empty($output)) { + $this->commands = $output; + return; + } + + if (isset($this->cache->style)) { + unset($this->cache->style); + } + + // $conf was a reference so it should just modify. + panels_edit_cache_set($this->cache); + + $this->commands[] = ctools_modal_command_dismiss(); + + if ($type == 'pane') { + $this->command_update_pane($pane); + } + else if ($type == 'region') { + $this->command_update_region_links($pid); + } + else { + $this->command_update_display_links(); + } + } + + /** + * AJAX entry point to configure CSS for a pane. + * + * @param $pid + * The pane id to edit. + */ + function ajax_pane_css($pid = NULL) { + if (empty($this->display->content[$pid])) { + ctools_modal_render(t('Error'), t('Invalid pane id.')); + } + + $pane = &$this->display->content[$pid]; + $subtype = ctools_content_get_subtype($pane->type, $pane->subtype); + + $form_state = array( + 'display' => &$this->display, + 'pane' => &$pane, + 'ajax' => TRUE, + 'title' => t('Configure CSS on !subtype_title', array('!subtype_title' => $subtype['title'])), + ); + + $output = ctools_modal_form_wrapper('panels_edit_configure_pane_css_form', $form_state); + if (!empty($output)) { + $this->commands = $output; + return; + } + + panels_edit_cache_set($this->cache); + $this->command_update_pane($pid); + $this->commands[] = ctools_modal_command_dismiss(); + } + + /** + * AJAX entry point to configure access settings for a pane. + * + * @param $pid + * The pane id to edit. + */ + function ajax_access_settings($pid = NULL) { + if (empty($this->display->content[$pid])) { + ctools_modal_render(t('Error'), t('Invalid pane id.')); + } + + $pane = &$this->display->content[$pid]; + $subtype = ctools_content_get_subtype($pane->type, $pane->subtype); + + $form_state = array( + 'display' => &$this->display, + 'pane' => &$pane, + 'ajax' => TRUE, + 'title' => t('Access settings on !subtype_title', array('!subtype_title' => $subtype['title'])), + ); + + $output = ctools_modal_form_wrapper('panels_edit_configure_access_settings_form', $form_state); + if (!empty($output)) { + $this->commands = $output; + return; + } + + panels_edit_cache_set($this->cache); + $this->command_update_pane($pid); + $this->commands[] = ctools_modal_command_dismiss(); + } + + /** + * AJAX entry point for to add a visibility rule. + */ + function ajax_access_add_test($pid = NULL) { + if (empty($this->display->content[$pid])) { + ctools_modal_render(t('Error'), t('Invalid pane id.')); + } + + $pane = &$this->display->content[$pid]; + $subtype = ctools_content_get_subtype($pane->type, $pane->subtype); + + $form_state = array( + 'display' => &$this->display, + 'pane' => &$pane, + 'ajax' => TRUE, + 'title' => t('Add visibility rule for !subtype_title', array('!subtype_title' => $subtype['title'])), + ); + + $output = ctools_modal_form_wrapper('panels_edit_add_access_test_form', $form_state); + if (empty($output)) { + // Set up the plugin in cache + $plugin = ctools_get_access_plugin($form_state['values']['type']); + $this->cache->new_plugin = ctools_access_new_test($plugin); + panels_edit_cache_set($this->cache); + + // go to the next step. + return $this->ajax_access_configure_test($pid, 'add'); + } + + ctools_ajax_render($output); + } + + /** + * AJAX entry point for to configure vsibility rule. + */ + function ajax_access_configure_test($pid = NULL, $id = NULL) { + if (empty($this->display->content[$pid])) { + ctools_modal_render(t('Error'), t('Invalid pane id.')); + } + + $pane = &$this->display->content[$pid]; + $subtype = ctools_content_get_subtype($pane->type, $pane->subtype); + + // Set this up here because $id gets changed later. + $url = $this->get_url('access-configure-test', $pid, $id); + + // If we're adding a new one, get the stored data from cache and + // add it. It's stored as a cache so that if this is closed + // we don't accidentally add an unconfigured plugin. + if ($id == 'add') { + $pane->access['plugins'][] = $this->cache->new_plugin; + $id = max(array_keys($pane->access['plugins'])); + } + else if (empty($pane->access['plugins'][$id])) { + ctools_modal_render(t('Error'), t('Invalid test id.')); + } + + $form_state = array( + 'display' => &$this->display, + 'pane' => &$pane, + 'ajax' => TRUE, + 'title' => t('Configure visibility rule for !subtype_title', array('!subtype_title' => $subtype['title'])), + 'test' => &$pane->access['plugins'][$id], + 'plugin' => ctools_get_access_plugin($pane->access['plugins'][$id]['name']), + 'url' => url($url, array('absolute' => TRUE)), + ); + + $output = ctools_modal_form_wrapper('panels_edit_configure_access_test_form', $form_state); + if (!empty($output)) { + $this->commands = $output; + return; + } + + // Unset the new plugin + if (isset($this->cache->new_plugin)) { + unset($this->cache->new_plugin); + } + + if (!empty($form_state['remove'])) { + unset($pane->access['plugins'][$id]); + } + + panels_edit_cache_set($this->cache); + $this->command_update_pane($pid); + $this->commands[] = ctools_modal_command_dismiss(); + } + + /** + * AJAX Router function for layout owned AJAX calls. + * + * Layouts like the flexible layout builder need callbacks of their own. + * This allows those layouts to simply declare their callbacks and use + * them with $this->get_url('layout', $command). + */ + function ajax_layout() { + $args = func_get_args(); + if (empty($args)) { + return MENU_NOT_FOUND; + } + + $command = array_shift($args); + if (empty($this->plugins['layout']['ajax'][$command]) || !function_exists($this->plugins['layout']['ajax'][$command])) { + return MENU_NOT_FOUND; + } + + // Make sure the this is always available to the called functions. + array_unshift($args, $this); + return call_user_func_array($this->plugins['layout']['ajax'][$command], $args); + } + + /** + * AJAX Router function for style owned AJAX calls. + * + * Styles like the stylizer need AJAX callbacks of their own. This + * allows the system to figure out which style is being referenced, + * load it, and execute the callback. + * + * This allows those layouts to simply declare their callbacks and use + * them using $this->get_url('style', $command, $type, $pid). + */ + function ajax_style() { + $args = func_get_args(); + if (count($args) < 3) { + return MENU_NOT_FOUND; + } + + $command = array_shift($args); + $type = array_shift($args); + $pid = array_shift($args); + + $info = $this->get_style($type, $pid); + + $style = $info[0]; + $conf = &$info[1]; + + if (empty($style['ajax'][$command]) || !function_exists($style['ajax'][$command])) { + return MENU_NOT_FOUND; + } + + // Make sure the this is always available to the called functions. + $args = array_merge(array(&$this, $style, &$conf, $type, $pid), $args); + return call_user_func_array($style['ajax'][$command], $args); + } + + // ------------------------------------------------------------------------ + // AJAX command generators + // + // These are used to make sure that child implementations can control their + // own AJAX commands as needed. + + /** + * Create a command array to redraw a pane. + */ + function command_update_pane($pid) { + if (is_object($pid)) { + $pane = $pid; + } + else { + $pane = $this->display->content[$pid]; + } + + $this->commands[] = ctools_ajax_command_replace("#panel-pane-$pane->pid", $this->render_pane($pane)); + $this->commands[] = ctools_ajax_command_changed("#panel-pane-$pane->pid", "div.grabber span.text"); + } + + /** + * Create a command array to add a new pane. + */ + function command_add_pane($pid) { + if (is_object($pid)) { + $pane = $pid; + } + else { + $pane = $this->display->content[$pid]; + } + + $this->commands[] = ctools_ajax_command_append("#panel-pane-$pane->panel", $this->render_pane($pane)); + $this->commands[] = ctools_ajax_command_changed("#panel-pane-$pane->pid", "div.grabber span.text"); + } + + /** + * Create a command to update the links on a display after a change was made. + */ + function command_update_display_links() { + $this->commands[] = ctools_ajax_command_replace('.panels-display-links', $this->get_display_links()); + } + + /** + * Create a command to update the links on a region after a change was made. + */ + function command_update_region_links($id) { + $this->commands[] = ctools_ajax_command_replace('.panels-region-links-' . $id, $this->get_region_links($id)); + } +} + +/** + * Handle the 'next' click on the add/edit pane form wizard. + * + * All we need to do is store the updated pane in the cache. + */ +function panels_ajax_edit_pane_next(&$form_state) { + $form_state['cache']->new_pane = $form_state['pane']; + panels_edit_cache_set($form_state['cache']); +} + +/** + * Handle the 'finish' click on teh add/edit pane form wizard. + * + * All we need to do is set a flag so the return can handle adding + * the pane. + */ +function panels_ajax_edit_pane_finish(&$form_state) { + $form_state['complete'] = TRUE; + return; +} + +/** + * Handle the 'cancel' click on the add/edit pane form wizard. + */ +function panels_ajax_edit_pane_cancel(&$form_state) { + $form_state['cancel'] = TRUE; + return; +} + +// -------------------------------------------------------------------------- +// Forms for the editor object + +/** + * Choose cache method form + */ +function panels_edit_cache_method_form(&$form_state) { + $display = &$form_state['display']; + $conf = &$form_state['conf']; + + // Set to 0 to ensure we get a selected radio. + if (!isset($conf['method'])) { + $conf['method'] = 0; + } + + $caches = panels_get_caches(); + if (empty($caches)) { + $form['markup'] = array('#value' => t('No caching options are available at this time. Please enable a panels caching module in order to use caching options.')); + return $form; + } + + $options[0] = t('No caching'); + foreach ($caches as $cache => $info) { + $options[$cache] = check_plain($info['title']); + } + + $form['method'] = array( + '#prefix' => '<div class="no-float">', + '#suffix' => '</div>', + '#type' => 'radios', + '#title' => t('Method'), + '#options' => $options, + '#default_value' => $conf['method'], + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Next'), + ); + return $form; +} + +/** + * Submit callback for panels_edit_cache_method_form. + * + * All this needs to do is return the method. + */ +function panels_edit_cache_method_form_submit($form, &$form_state) { + $form_state['method'] = $form_state['values']['method']; +} + +/** + * Cache settings form + */ +function panels_edit_cache_settings_form(&$form_state) { + $display = &$form_state['display']; + $conf = &$form_state['conf']; + $pid = $form_state['pid']; + $info = panels_get_cache($conf['method']); + + $form['#action'] = $form_state['url']; + + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => check_plain($info['description']), + ); + + $function = panels_plugin_get_function('cache', $conf['method'], 'settings form'); + + $form['settings'] = $function($conf['settings'], $display, $pid); + $form['settings']['#tree'] = TRUE; + + $form['display'] = array( + '#type' => 'value', + '#value' => $display, + ); + + $form['pid'] = array( + '#type' => 'value', + '#value' => $pid, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +/** + * Validate cache settings. + */ +function panels_edit_cache_settings_form_validate($form, &$form_state) { + if ($function = panels_plugin_get_function('cache', $form_state['conf']['method'], 'settings form validate')) { + $function($form, $form_state['values']['settings']); + } +} + +/** + * Allows panel styles to validate their style settings. + */ +function panels_edit_cache_settings_form_submit($form, &$form_state) { + if ($function = panels_plugin_get_function('cache', $form_state['conf']['method'], 'settings form submit')) { + $function($form_state['values']['settings']); + } + + $form_state['conf']['settings'] = $form_state['values']['settings']; +} + +/** + * Choose style form + */ +function panels_edit_style_type_form(&$form_state) { + $display = &$form_state['display']; + $style = $form_state['style']; + $type = $form_state['type']; + + $styles = panels_get_styles(); + + $function = ($type == 'pane' ? 'render pane' : (variable_get('panels_legacy_rendering_mode', TRUE) ? 'render panel' : 'render region')); + $options = array(); + if ($type == 'region') { + $options[-1] = t('Use display default style'); + } + + uasort($styles, 'ctools_plugin_sort'); + + foreach ($styles as $id => $info) { + if (empty($info['hidden']) && (!empty($info[$function]) || $id == 'default')) { + $options[$id] = check_plain($info['title']); + } + } + + $form['style'] = array( + '#prefix' => '<div class="no-float">', + '#suffix' => '</div>', + '#type' => 'radios', + '#title' => t('Style'), + '#options' => $options, + '#default_value' => $style, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Next'), + ); + return $form; +} + +/** + * Submit callback for panels_edit_style_type_form. + * + * All this needs to do is return the method. + */ +function panels_edit_style_type_form_submit($form, &$form_state) { + $form_state['old_style'] = $form_state['style']; + $form_state['style'] = $form_state['values']['style']; +} + +/** + * Style settings form + */ +function panels_edit_style_settings_form(&$form_state) { + $display = &$form_state['display']; + $conf = &$form_state['conf']; + $pid = $form_state['pid']; + $style = $form_state['style']; + $type = $form_state['type']; + + $form['#action'] = $form_state['url']; + + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => check_plain($style['description']), + ); + + $function = panels_plugin_get_function('styles', $style, ($type == 'pane') ? 'pane settings form' : 'settings form'); + + $form['settings'] = $function($conf, $display, $pid, $type, $form_state); + $form['settings']['#tree'] = TRUE; + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +/** + * Validate style settings. + */ +function panels_edit_style_settings_form_validate($form, &$form_state) { + $name = $form_state['type'] == 'pane' ? 'pane settings form validate' : 'settings form validate'; + if ($function = panels_plugin_get_function('styles', $form_state['style'], $name)) { + $function($form, $form_state['values']['settings'], $form_state); + } +} + +/** + * Allows panel styles to validate their style settings. + */ +function panels_edit_style_settings_form_submit($form, &$form_state) { + $name = $form_state['type'] == 'pane' ? 'pane settings form submit' : 'settings form submit'; + if ($function = panels_plugin_get_function('styles', $form_state['style'], $name)) { + $function($form, $form_state['values']['settings'], $form_state); + } + + $form_state['conf'] = $form_state['values']['settings']; +} + + +/** + * Configure CSS on a pane form. + */ +function panels_edit_configure_pane_css_form(&$form_state) { + $display = &$form_state['display']; + $pane = &$form_state['pane']; + + $form['css_id'] = array( + '#type' => 'textfield', + '#default_value' => isset($pane->css['css_id']) ? $pane->css['css_id'] : '', + '#title' => t('CSS ID'), + '#description' => t('CSS ID to apply to this pane. This may be blank.'), + ); + $form['css_class'] = array( + '#type' => 'textfield', + '#default_value' => isset($pane->css['css_class']) ? $pane->css['css_class'] : '', + '#title' => t('CSS class'), + '#description' => t('CSS class to apply to this pane. This may be blank.'), + ); + + $form['next'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +/** + * FAPI submission function for the CSS configure form. + * + * All this does is set up $pane properly. The caller is responsible for + * actually storing this somewhere. + */ +function panels_edit_configure_pane_css_form_submit($form, &$form_state) { + $pane = &$form_state['pane']; + $display = $form_state['display']; + + $pane->css['css_id'] = $form_state['values']['css_id']; + $pane->css['css_class'] = $form_state['values']['css_class']; +} + +/** + * Form to control basic visibility settings. + */ +function panels_edit_configure_access_settings_form(&$form_state) { + $display = &$form_state['display']; + $pane = &$form_state['pane']; + + $form['logic'] = array( + '#type' => 'radios', + '#options' => array( + 'and' => t('All criteria must pass.'), + 'or' => t('Only one criterion must pass.'), + ), + '#default_value' => isset($pane->access['logic']) ? $pane->access['logic'] : 'and', + ); + + $form['next'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +/** + * FAPI submission function for the edit access settings form. + * + * All this does is set up $pane properly. The caller is responsible for + * actually storing this somewhere. + */ +function panels_edit_configure_access_settings_form_submit($form, &$form_state) { + $pane = &$form_state['pane']; + $display = $form_state['display']; + + $pane->access['logic'] = $form_state['values']['logic']; +} + +/** + * Form to add a visibility rule. + */ +function panels_edit_add_access_test_form(&$form_state) { + $display = &$form_state['display']; + $pane = &$form_state['pane']; + + $plugins = ctools_get_relevant_access_plugins($display->context); + $options = array(); + foreach ($plugins as $id => $plugin) { + $options[$id] = $plugin['title']; + } + + asort($options); + + $form['type'] = array( + // This ensures that the form item is added to the URL. + '#type' => 'radios', + '#options' => $options, + ); + + $form['next'] = array( + '#type' => 'submit', + '#value' => t('Next'), + ); + + return $form; +} + +/** + * Form to configure a visibility rule. + */ +function panels_edit_configure_access_test_form(&$form_state) { + $display = &$form_state['display']; + $test = &$form_state['test']; + $plugin = &$form_state['plugin']; + + $form['#action'] = $form_state['url']; + + $contexts = $display->context; + if (!isset($contexts['logged-in-user'])) { + $contexts['logged-in-user'] = ctools_access_get_loggedin_context(); + } + + if (isset($plugin['required context'])) { + $form['context'] = ctools_context_selector($contexts, $plugin['required context'], $test['context']); + } + + $form['settings'] = array('#tree' => TRUE); + if ($function = ctools_plugin_get_function($plugin, 'settings form')) { + $function($form, $form_state, $test['settings']); + } + + $form['not'] = array( + '#type' => 'checkbox', + '#title' => t('Reverse (NOT)'), + '#default_value' => !empty($test['not']), + ); + + $form['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + $form['remove'] = array( + '#type' => 'submit', + '#value' => t('Remove'), + '#remove' => TRUE, + ); + + return $form; +} + +/** + * Validate handler for visibility rule settings + */ +function panels_edit_configure_access_test_form_validate(&$form, &$form_state) { + if (!empty($form_state['clicked_button']['#remove'])) { + return; + } + + if ($function = ctools_plugin_get_function($form_state['plugin'], 'settings form validate')) { + $function($form, $form_state); + } +} + +/** + * Submit handler for visibility rule settings + */ +function panels_edit_configure_access_test_form_submit(&$form, &$form_state) { + if (!empty($form_state['clicked_button']['#remove'])) { + $form_state['remove'] = TRUE; + return; + } + + if ($function = ctools_plugin_get_function($form_state['plugin'], 'settings form submit')) { + $function($form, $form_state); + } + + $form_state['test']['settings'] = $form_state['values']['settings']; + if (isset($form_state['values']['context'])) { + $form_state['test']['context'] = $form_state['values']['context']; + } + $form_state['test']['not'] = !empty($form_state['values']['not']); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_legacy.class.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_legacy.class.php new file mode 100644 index 0000000000000000000000000000000000000000..42fb01c20dd1064b2f47742b3f93979aaa0e451b --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_legacy.class.php @@ -0,0 +1,294 @@ +<?php + +/** + * Legacy render pipeline for a panels display. + * + * This render pipeline mirrors the old procedural system exactly, and plugins + * written for the legacy system will work exactly as they did before with this + * renderer. + * + * Most plugins will work with the newer renderer. These are the exceptions: + * - Style plugins that implement panel styling no longer need to call + * panels_render_pane() on all contained panes; rendered pane HTML is now + * passed in directly. + * - Cache plugins are now triggered on rendered HTML, rather than on + * unrendered datastructures, when acting at the display level. When acting + * at the pane level, they still receive the unrendered datastructure. + * + * If your site relies on any of these plugin behaviors, you will need to use + * this renderer instead of the new panels_renderer_standard() until those + * plugins are updated. + */ +class panels_renderer_legacy { + var $meta_location = 'standard'; + + var $display; + var $plugins = array(); + + /** + * Include rendered HTML prior to the layout. + * + * @var string + */ + var $prefix = ''; + + /** + * Include rendered HTML after the layout. + * + * @var string + */ + var $suffix = ''; + + function init($plugin, &$display) { + $this->plugin = $plugin; + $this->plugins['layout'] = panels_get_layout($display->layout); + if (empty($this->plugins['layout'])) { + watchdog('panels', "Layout: @layout couldn't been found, maybe the theme is disabled.", array('@layout' => $display->layout)); + } + $this->display = &$display; + } + + /** + * Add CSS information to the renderer. + * + * To facilitate previews over Views, CSS can now be added in a manner + * that does not necessarily mean just using drupal_add_css. Therefore, + * during the panel rendering process, this method can be used to add + * css and make certain that ti gets to the proper location. + * + * The arguments should exactly match drupal_add_css(). + * + * @see drupal_add_css + */ + function add_css($filename, $type = 'module', $media = 'all', $preprocess = TRUE) { + $path = file_create_path($filename); + switch ($this->meta_location) { + case 'standard': + if ($path) { + // Use CTools CSS add because it can handle temporary CSS in private + // filesystem. + ctools_include('css'); + ctools_css_add_css($filename, $type, $media, $preprocess); + } + else { + drupal_add_css($filename, $type, $media, $preprocess); + } + break; + case 'inline': + if ($path) { + $url = file_create_url($filename); + } + else { + $url = base_path() . $filename; + } + + $this->prefix .= '<link type="text/css" rel="stylesheet" media="' . $media . '" href="' . $url . '" />'."\n"; + break; + } + } + + /** + * Builds inner content, then hands off to layout-specified theme function for + * final render step. + * + * This is the outermost method in the Panels render pipeline. It calls the + * inner methods, which return a content array, which is in turn passed to the + * theme function specified in the layout plugin. + * + * @return string + * Themed & rendered HTML output. + */ + function render() { + if (!empty($this->plugins['layout']['css'])) { + if (file_exists(path_to_theme() . '/' . $this->plugins['layout']['css'])) { + drupal_add_css(path_to_theme() . '/' . $this->plugins['layout']['css']); + } + else { + drupal_add_css($this->plugins['layout']['path'] . '/' . $this->plugins['layout']['css']); + } + } + // This now comes after the CSS is added, because panels-within-panels must + // have their CSS added in the right order; inner content before outer content. + + if (empty($this->display->cache['method']) || !empty($this->display->skip_cache)) { + $content = $this->render_regions(); + } + else { + $cache = panels_get_cached_content($this->display, $this->display->args, $this->display->context); + if ($cache === FALSE) { + $cache = new panels_cache_object(); + $cache->set_content($this->render_regions()); + panels_set_cached_content($cache, $this->display, $this->display->args, $this->display->context); + } + $content = $cache->content; + } + + $output = theme($this->plugins['layout']['theme'], check_plain($this->display->css_id), $content, $this->display->layout_settings, $this->display, $this->plugins['layout'], $this); + + return $this->prefix . $output . $this->suffix; + } + + /** + * Render all panes in the attached display into their panel regions, then + * render those regions. + * + * @return array $content + * An array of rendered panel regions, keyed on the region name. + */ + function render_regions() { + ctools_include('content'); + + // First, render all the panes into little boxes. We do this here because + // some panes request to be rendered after other panes (primarily so they + // can do the leftovers of forms). + $panes = $first = $normal = $last = array(); + + foreach ($this->display->content as $pid => $pane) { + $pane->shown = !empty($pane->shown); // guarantee this field exists. + // If the user can't see this pane, do not render it. + if (!$pane->shown || !panels_pane_access($pane, $this->display)) { + continue; + } + + $content_type = ctools_get_content_type($pane->type); + + // If this pane wants to render last, add it to the $last array. We allow + // this because some panes need to be rendered after other panes, + // primarily so they can do things like the leftovers of forms. + if (!empty($content_type['render last'])) { + $last[$pid] = $pane; + } + // If it wants to render first, add it to the $first array. This is used + // by panes that need to do some processing before other panes are + // rendered. + else if (!empty($content_type['render first'])) { + $first[$pid] = $pane; + } + // Otherwise, render it in the normal order. + else { + $normal[$pid] = $pane; + } + } + + foreach (($first + $normal + $last) as $pid => $pane) { + $panes[$pid] = $this->render_pane($pane); + } + + // Loop through all panels, put all panes that belong to the current panel + // in an array, then render the panel. Primarily this ensures that the + // panes are in the proper order. + $content = array(); + foreach ($this->display->panels as $panel_name => $pids) { + $panel_panes = array(); + foreach ($pids as $pid) { + if (!empty($panes[$pid])) { + $panel_panes[$pid] = $panes[$pid]; + } + } + $content[$panel_name] = $this->render_region($panel_name, $panel_panes); + } + + // Prevent notices by making sure that all panels at least have an entry: + $panels = panels_get_regions($this->plugins['layout'], $this->display); + foreach ($panels as $id => $panel) { + if (!isset($content[$id])) { + $content[$id] = NULL; + } + } + + return $content; + } + + /** + * Render the contents of a single pane. + * + * This method retrieves pane content and produces a ready-to-render content + * object. It also manages pane-specific caching. + * + * @param stdClass $pane + * A Panels pane object, as loaded from the database. + */ + function render_pane(&$pane) { + ctools_include('context'); + if (!is_array($this->display->context)) { + $this->display->context = array(); + } + + $content = FALSE; + $caching = !empty($pane->cache['method']) && empty($this->display->skip_cache); + if ($caching && ($cache = panels_get_cached_content($this->display, $this->display->args, $this->display->context, $pane))) { + $content = $cache->content; + } + else { + $content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, array(), $this->display->args, $this->display->context); + foreach (module_implements('panels_pane_content_alter') as $module) { + $function = $module . '_panels_pane_content_alter'; + $function($content, $pane, $this->display->args, $this->display->context); + } + if ($caching) { + $cache = new panels_cache_object(); + $cache->set_content($content); + panels_set_cached_content($cache, $this->display, $this->display->args, $this->display->context, $pane); + $content = $cache->content; + } + } + + // Pass long the css_id that is usually available. + if (!empty($pane->css['css_id'])) { + $content->css_id = $pane->css['css_id']; + } + + // Pass long the css_class that is usually available. + if (!empty($pane->css['css_class'])) { + $content->css_class = $pane->css['css_class']; + } + + return $content; + } + + /** + * Render a single panel region. + * + * Primarily just a passthrough to the panel region rendering callback + * specified by the style plugin that is attached to the current panel region. + * + * @param $region_name + * The ID of the panel region being rendered + * @param $panes + * An array of panes that are assigned to the panel that's being rendered. + * + * @return + * The rendered HTML for the passed-in panel region. + */ + function render_region($region_name, $panes) { + list($style, $style_settings) = panels_get_panel_style_and_settings($this->display->panel_settings, $region_name); + $callback = 'render panel'; + + // Retrieve the pid (can be a panel page id, a mini panel id, etc.), this + // might be used (or even necessary) for some panel display styles. + $owner_id = 0; + if (isset($this->display->owner) && is_object($this->display->owner) && isset($this->display->owner->id)) { + $owner_id = $this->display->owner->id; + } + + // Check to see if we're actually running a current style plugin even though + // we're in the legacy renderer + if (version_compare($style['version'], 2.0, '>=')) { + // We are, so pre-render the content as the current version expects + foreach($panes as $pane_id => $pane) { + $content = panels_render_pane($pane, $this->display->content[$pane_id], $this->display); + if ($content) { + $panes[$pane_id] = $content; + } + else { + unset($panes[$pane_id]); + } + } + // And set the callback to the new key + $callback = 'render region'; + + } + + return theme($style[$callback], $this->display, $owner_id, $panes, $style_settings, $region_name, $style); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_simple.class.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_simple.class.php new file mode 100644 index 0000000000000000000000000000000000000000..9a813ac68c3416f730f2dafc49eef1a4c130716f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_simple.class.php @@ -0,0 +1,32 @@ +<?php +/** + * @file + * Contains the simple display renderer. + */ + +/** + * The simple display renderer renders a display normally, except each pane + * is already rendered content, rather than a pane containing CTools content + * to be rendered. Styles are not supported. + */ +class panels_renderer_simple extends panels_renderer_standard { + function render_regions() { + $this->rendered['regions'] = array(); + foreach ($this->display->content as $region_id => $content) { + if (is_array($content)) { + $content = implode('', $content); + } + + $this->rendered['regions'][$region_id] = $content; + } + return $this->rendered['regions']; + } + + function render_panes() { + // NOP + } + + function prepare() { + $this->prep_run = TRUE; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_single_pane.class.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_single_pane.class.php new file mode 100644 index 0000000000000000000000000000000000000000..ccdebaf1fd9b9d21915d5499a7a062e5ea0431b2 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_single_pane.class.php @@ -0,0 +1,41 @@ +<?php + +class panels_renderer_single_pane extends panels_renderer_standard { + /** + * The pane id of the pane that will be rendered by a call to the render() + * method. Numeric int or string (typically if a new-# id has been used). + * @var mixed + */ + var $render_pid; + + /** + * Modified build method (vs. panels_renderer_standard::build()); takes just + * the display, no layout is necessary. + * + * @param array $plugin + * The definition of the renderer plugin. + * + * @param panels_display $display + * The panels display object to be rendered. + */ + function init($plugin, &$display) { + $this->plugin = $plugin; + $this->display = &$display; + } + + function prepare($external_settings = NULL) { + $this->render_pid = $external_settings; + } + + function render() { + // If no requested pid, or requested pid does not exist, + if (empty($this->render_pid) || empty($this->display->content[$this->render_pid])) { + return NULL; + } + return $this->render_pane($this->display->content[$this->render_pid]); + } + + function render_single($pid) { + return $this->render_pane($this->display->content[$pid]); + } +} \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_standard.class.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_standard.class.php new file mode 100644 index 0000000000000000000000000000000000000000..fcd9fed216736a0339721071b0e482b9dfe795b1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/panels_renderer_standard.class.php @@ -0,0 +1,629 @@ +<?php + +/** + * The standard render pipeline for a Panels display object. + * + * Given a fully-loaded panels_display object, this class will turn its + * combination of layout, panes, and styles into HTML, invoking caching + * appropriately along the way. Interacting with the renderer externally is + * very simple - just pass it the display object and call the render() method: + * + * @code + * // given that $display is a fully loaded Panels display object + * $renderer = panels_get_renderer_handler('standard', $display) + * $html_output = $renderer->render(); + * @endcode + * + * Internally, the render pipeline is divided into two phases, prepare and + * render: + * - The prepare phase transforms the skeletal data on the provided + * display object into a structure that is expected by the render phase. + * It is divided into a series of discrete sub-methods and operates + * primarily by passing parameters, all with the intention of making + * subclassing easier. + * - The render phase relies primarily on data stored in the renderer object's + * properties, presumably set in the prepare phase. It iterates through the + * rendering of each pane, pane styling, placement in panel regions, region + * styling, and finally the arrangement of rendered regions in the layout. + * Caching, if in use, is triggered per pane, or on the entire display. + * + * In short: prepare builds conf, render renders conf. Subclasses should respect + * this separation of responsibilities by adhering to these loose guidelines, + * given a loaded display object: + * - If your renderer needs to modify the datastructure representing what is + * to be rendered (panes and their conf, styles, caching, etc.), it should + * use the prepare phase. + * - If your renderer needs to modify the manner in which that renderable + * datastructure data is rendered, it should use the render phase. + * + * In the vast majority of use cases, this standard renderer will be sufficient + * and need not be switched out/subclassed; style and/or layout plugins can + * accommodate nearly every use case. If you think you might need a custom + * renderer, consider the following criteria/examples: + * - Some additional markup needs to be added to EVERY SINGLE panel. + * - Given a full display object, just render one pane. + * - Show a Panels admin interface. + * + * The system is almost functionally identical to the old procedural approach, + * with some exceptions (@see panels_renderer_legacy for details). The approach + * here differs primarily in its friendliness to tweaking in subclasses. + */ +class panels_renderer_standard { + /** + * The fully-loaded Panels display object that is to be rendered. "Fully + * loaded" is defined as: + * 1. Having been produced by panels_load_displays(), whether or this page + * request or at some time in the past and the object was exported. + * 2. Having had some external code attach context data ($display->context), + * in the exact form expected by panes. Context matching is delicate, + * typically relying on exact string matches, so special attention must + * be taken. + * + * @var panels_display + */ + var $display; + + /** + * An associative array of loaded plugins. Used primarily as a central + * location for storing plugins that require additional loading beyond + * reading the plugin definition, which is already statically cached by + * ctools_get_plugins(). An example is layout plugins, which can optionally + * have a callback that determines the set of panel regions available at + * runtime. + * + * @var array + */ + var $plugins = array(); + + /** + * A multilevel array of rendered data. The first level of the array + * indicates the type of rendered data, typically with up to three keys: + * 'layout', 'regions', and 'panes'. The relevant rendered data is stored as + * the value for each of these keys as it is generated: + * - 'panes' are an associative array of rendered output, keyed on pane id. + * - 'regions' are an associative array of rendered output, keyed on region + * name. + * - 'layout' is the whole of the rendered output. + * + * @var array + */ + var $rendered = array(); + + /** + * A multilevel array of data prepared for rendering. The first level of the + * array indicates the type of prepared data. The standard renderer populates + * and uses two top-level keys, 'panes' and 'regions': + * - 'panes' are an associative array of pane objects to be rendered, keyed + * on pane id and sorted into proper rendering order. + * - 'regions' are an associative array of regions, keyed on region name, + * each of which is itself an indexed array of pane ids in the order in + * which those panes appear in that region. + * + * @var array + */ + var $prepared = array(); + + /** + * Boolean state variable, indicating whether or not the prepare() method has + * been run. + * + * This state is checked in panels_renderer_standard::render_layout() to + * determine whether the prepare method should be automatically triggered. + * + * @var bool + */ + var $prep_run = FALSE; + + /** + * The plugin that defines this handler. + */ + var $plugin = FALSE; + + /** + * TRUE if this renderer is rendering in administrative mode + * which will allow layouts to have extra functionality. + * + * @var bool + */ + var $admin = FALSE; + + /** + * Where to add standard meta information. There are three possibilities: + * - standard: Put the meta information in the normal location. Default. + * - inline: Put the meta information directly inline. This will + * not work for javascript. + * + * @var string + */ + var $meta_location = 'standard'; + + /** + * Include rendered HTML prior to the layout. + * + * @var string + */ + var $prefix = ''; + + /** + * Include rendered HTML after the layout. + * + * @var string + */ + var $suffix = ''; + + /** + * Receive and store the display object to be rendered. + * + * This is a psuedo-constructor that should typically be called immediately + * after object construction. + * + * @param array $plugin + * The definition of the renderer plugin. + * @param panels_display $display + * The panels display object to be rendered. + */ + function init($plugin, &$display) { + $this->plugin = $plugin; + $layout = panels_get_layout($display->layout); + $this->display = &$display; + $this->plugins['layout'] = $layout; + if (!isset($layout['panels'])) { + $this->plugins['layout']['panels'] = panels_get_regions($layout, $display); + } + + if (empty($this->plugins['layout'])) { + watchdog('panels', "Layout: @layout couldn't been found, maybe the theme is disabled.", array('@layout' => $display->layout)); + } + } + + /** + * Prepare the attached display for rendering. + * + * This is the outermost prepare method. It calls several sub-methods as part + * of the overall preparation process. This compartmentalization is intended + * to ease the task of modifying renderer behavior in child classes. + * + * If you override this method, it is important that you either call this + * method via parent::prepare(), or manually set $this->prep_run = TRUE. + * + * @param mixed $external_settings + * An optional parameter allowing external code to pass in additional + * settings for use in the preparation process. Not used in the default + * renderer, but included for interface consistency. + */ + function prepare($external_settings = NULL) { + $this->prepare_panes($this->display->content); + $this->prepare_regions($this->display->panels, $this->display->panel_settings); + $this->prep_run = TRUE; + } + + /** + * Prepare the list of panes to be rendered, accounting for visibility/access + * settings and rendering order. + * + * This method represents the standard approach for determining the list of + * panes to be rendered that is compatible with all parts of the Panels + * architecture. It first applies visibility & access checks, then sorts panes + * into their proper rendering order, and returns the result as an array. + * + * Inheriting classes should override this method if that renderer needs to + * regularly make additions to the set of panes that will be rendered. + * + * @param array $panes + * An associative array of pane data (stdClass objects), keyed on pane id. + * @return array + * An associative array of panes to be rendered, keyed on pane id and sorted + * into proper rendering order. + */ + function prepare_panes($panes) { + ctools_include('content'); + // Use local variables as writing to them is very slightly faster + $first = $normal = $last = array(); + + // Prepare the list of panes to be rendered + foreach ($panes as $pid => $pane) { + if (empty($this->admin)) { + // TODO remove in 7.x and ensure the upgrade path weeds out any stragglers; it's been long enough + $pane->shown = !empty($pane->shown); // guarantee this field exists. + // If this pane is not visible to the user, skip out and do the next one + if (!$pane->shown || !panels_pane_access($pane, $this->display)) { + continue; + } + } + + $content_type = ctools_get_content_type($pane->type); + + // If this pane wants to render last, add it to the $last array. We allow + // this because some panes need to be rendered after other panes, + // primarily so they can do things like the leftovers of forms. + if (!empty($content_type['render last'])) { + $last[$pid] = $pane; + } + // If it wants to render first, add it to the $first array. This is used + // by panes that need to do some processing before other panes are + // rendered. + else if (!empty($content_type['render first'])) { + $first[$pid] = $pane; + } + // Otherwise, render it in the normal order. + else { + $normal[$pid] = $pane; + } + } + $this->prepared['panes'] = $first + $normal + $last; + return $this->prepared['panes']; + } + + /** + * Prepare the list of regions to be rendered. + * + * This method is primarily about properly initializing the style plugin that + * will be used to render the region. This is crucial as regions cannot be + * rendered without a style plugin (in keeping with Panels' philosophy of + * hardcoding none of its output), but for most regions no style has been + * explicitly set. The logic here is what accommodates that situation: + * - If a region has had its style explicitly set, then we fetch that plugin + * and continue. + * - If the region has no explicit style, but a style was set at the display + * level, then inherit the style from the display. + * - If neither the region nor the dispay have explicitly set styles, then + * fall back to the hardcoded 'default' style, a very minimal style. + * + * The other important task accomplished by this method is ensuring that even + * regions without any panes are still properly prepared for the rendering + * process. This is essential because the way Panels loads display objects + * (@see panels_load_displays) results only in a list of regions that + * contain panes - not necessarily all the regions defined by the layout + * plugin, which can only be determined by asking the plugin at runtime. This + * method consults that retrieved list of regions and prepares all of those, + * ensuring none are inadvertently skipped. + * + * @param array $region_pane_list + * An associative array of pane ids, keyed on the region to which those pids + * are assigned. In the default case, this is $display->panels. + * @param array $settings + * All known region style settings, including both the top-level display's + * settings (if any) and all region-specific settings (if any). + * @return array + * An array of regions prepared for rendering. + */ + function prepare_regions($region_pane_list, $settings) { + // Initialize defaults to be used for regions without their own explicit + // settings. Use display settings if they exist, else hardcoded defaults. + $default = array( + 'style' => panels_get_style(!empty($settings['style']) ? $settings['style'] : 'default'), + 'style settings' => isset($settings['style_settings']['default']) ? $settings['style_settings']['default'] : array(), + ); + + $regions = array(); + if (empty($settings)) { + // No display/panel region settings exist, init all with the defaults. + foreach ($this->plugins['layout']['panels'] as $region_id => $title) { + // Ensure this region has at least an empty panes array. + $panes = !empty($region_pane_list[$region_id]) ? $region_pane_list[$region_id] : array(); + + $regions[$region_id] = $default; + $regions[$region_id]['pids'] = $panes; + } + } + else { + // Some settings exist; iterate through each region and set individually. + foreach ($this->plugins['layout']['panels'] as $region_id => $title) { + // Ensure this region has at least an empty panes array. + $panes = !empty($region_pane_list[$region_id]) ? $region_pane_list[$region_id] : array(); + + if (empty($settings[$region_id]['style']) || $settings[$region_id]['style'] == -1) { + $regions[$region_id] = $default; + } + else { + $regions[$region_id]['style'] = panels_get_style($settings[$region_id]['style']); + $regions[$region_id]['style settings'] = isset($settings['style_settings'][$region_id]) ? $settings['style_settings'][$region_id] : array(); + } + $regions[$region_id]['pids'] = $panes; + } + } + + $this->prepared['regions'] = $regions; + return $this->prepared['regions']; + } + + /** + * Build inner content, then hand off to layout-specified theme function for + * final render step. + * + * This is the outermost method in the Panels render pipeline. It calls the + * inner methods, which return a content array, which is in turn passed to the + * theme function specified in the layout plugin. + * + * @return string + * Themed & rendered HTML output. + */ + function render() { + // Attach out-of-band data first. + $this->add_meta(); + + if (empty($this->display->cache['method']) || !empty($this->display->skip_cache)) { + return $this->render_layout(); + } + else { + $cache = panels_get_cached_content($this->display, $this->display->args, $this->display->context); + if ($cache === FALSE) { + $cache = new panels_cache_object(); + $cache->set_content($this->render_layout()); + panels_set_cached_content($cache, $this->display, $this->display->args, $this->display->context); + } + return $cache->content; + } + } + + /** + * Perform display/layout-level render operations. + * + * This method triggers all the inner pane/region rendering processes, passes + * that to the layout plugin's theme callback, and returns the rendered HTML. + * + * If display-level caching is enabled and that cache is warm, this method + * will not be called. + * + * @return string + * The HTML string representing the entire rendered, themed panel. + */ + function render_layout() { + if (empty($this->prep_run)) { + $this->prepare(); + } + $this->render_panes(); + $this->render_regions(); + + if ($this->admin && !empty($this->plugins['layout']['admin theme'])) { + $theme = $this->plugins['layout']['admin theme']; + } + else { + $theme = $this->plugins['layout']['theme']; + } + $this->rendered['layout'] = theme($theme, check_plain($this->display->css_id), $this->rendered['regions'], $this->display->layout_settings, $this->display, $this->plugins['layout'], $this); + return $this->prefix . $this->rendered['layout'] . $this->suffix; + } + + /** + * Attach out-of-band page metadata (e.g., CSS and JS). + * + * This must be done before render, because panels-within-panels must have + * their CSS added in the right order: inner content before outer content. + */ + function add_meta() { + if (!empty($this->plugins['layout']['css'])) { + if (file_exists(path_to_theme() . '/' . $this->plugins['layout']['css'])) { + $this->add_css(path_to_theme() . '/' . $this->plugins['layout']['css']); + } + else { + $this->add_css($this->plugins['layout']['path'] . '/' . $this->plugins['layout']['css']); + } + } + + if ($this->admin && isset($this->plugins['layout']['admin css'])) { + $this->add_css($this->plugins['layout']['path'] . '/' . $this->plugins['layout']['admin css']); + } + } + + /** + * Add CSS information to the renderer. + * + * To facilitate previews over Views, CSS can now be added in a manner + * that does not necessarily mean just using drupal_add_css. Therefore, + * during the panel rendering process, this method can be used to add + * css and make certain that ti gets to the proper location. + * + * The arguments should exactly match drupal_add_css(). + * + * @see drupal_add_css + */ + function add_css($filename, $type = 'module', $media = 'all', $preprocess = TRUE) { + $path = file_create_path($filename); + switch ($this->meta_location) { + case 'standard': + if ($path) { + // Use CTools CSS add because it can handle temporary CSS in private + // filesystem. + ctools_include('css'); + ctools_css_add_css($filename, $type, $media, $preprocess); + } + else { + drupal_add_css($filename, $type, $media, $preprocess); + } + break; + case 'inline': + if ($path) { + $url = file_create_url($filename); + } + else { + $url = base_path() . $filename; + } + + $this->prefix .= '<link type="text/css" rel="stylesheet" media="' . $media . '" href="' . $url . '" />'."\n"; + break; + } + } + + /** + * Render all prepared panes, first by dispatching to their plugin's render + * callback, then handing that output off to the pane's style plugin. + * + * @return array + * The array of rendered panes, keyed on pane pid. + */ + function render_panes() { + ctools_include('content'); + + // First, render all the panes into little boxes. + $this->rendered['panes'] = array(); + foreach ($this->prepared['panes'] as $pid => $pane) { + $content = $this->render_pane($pane); + if ($content) { + $this->rendered['panes'][$pid] = $content; + } + } + return $this->rendered['panes']; + } + + /** + * Render a pane using its designated style. + * + * This method also manages 'title pane' functionality, where the title from + * an individual pane can be bubbled up to take over the title for the entire + * display. + * + * @param stdClass $pane + * A Panels pane object, as loaded from the database. + */ + function render_pane(&$pane) { + $content = $this->render_pane_content($pane); + if ($this->display->hide_title == PANELS_TITLE_PANE && !empty($this->display->title_pane) && $this->display->title_pane == $pane->pid) { + + // If the user selected to override the title with nothing, and selected + // this as the title pane, assume the user actually wanted the original + // title to bubble up to the top but not actually be used on the pane. + if (empty($content->title) && !empty($content->original_title)) { + $this->display->stored_pane_title = $content->original_title; + } + else { + $this->display->stored_pane_title = !empty($content->title) ? $content->title : ''; + } + } + + if (!empty($content->content)) { + if (!empty($pane->style['style'])) { + $style = panels_get_style($pane->style['style']); + + if (isset($style) && isset($style['render pane'])) { + $output = theme($style['render pane'], $content, $pane, $this->display, $style); + + // This could be null if no theme function existed. + if (isset($output)) { + return $output; + } + } + } + + // fallback + return theme('panels_pane', $content, $pane, $this->display); + } + } + + /** + * Render the interior contents of a single pane. + * + * This method retrieves pane content and produces a ready-to-render content + * object. It also manages pane-specific caching. + * + * @param stdClass $pane + * A Panels pane object, as loaded from the database. + * @return stdClass $content + * A renderable object, containing a subject, content, etc. Based on the + * renderable objects used by the block system. + */ + function render_pane_content(&$pane) { + ctools_include('context'); + // TODO finally safe to remove this check? + if (!is_array($this->display->context)) { + watchdog('panels', 'renderer::render_pane_content() hit with a non-array for the context', $this->display, WATCHDOG_DEBUG); + $this->display->context = array(); + } + + $content = FALSE; + $caching = !empty($pane->cache['method']) && empty($this->display->skip_cache); + if ($caching && ($cache = panels_get_cached_content($this->display, $this->display->args, $this->display->context, $pane))) { + $content = $cache->content; + } + else { + if ($caching) { + $cache = new panels_cache_object(); + } + $content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, array(), $this->display->args, $this->display->context); + if (empty($content)) { + return; + } + + foreach (module_implements('panels_pane_content_alter') as $module) { + $function = $module . '_panels_pane_content_alter'; + $function($content, $pane, $this->display->args, $this->display->context); + } + + if ($caching && isset($cache)) { + $cache->set_content($content); + panels_set_cached_content($cache, $this->display, $this->display->args, $this->display->context, $pane); + $content = $cache->content; + } + } + + // Pass long the css_id that is usually available. + if (!empty($pane->css['css_id'])) { + $content->css_id = check_plain($pane->css['css_id']); + } + + // Pass long the css_class that is usually available. + if (!empty($pane->css['css_class'])) { + $content->css_class = check_plain($pane->css['css_class']); + } + + return $content; + } + + /** + * Render all prepared regions, placing already-rendered panes into their + * appropriate positions therein. + * + * @return array + * An array of rendered panel regions, keyed on the region name. + */ + function render_regions() { + $this->rendered['regions'] = array(); + + // Loop through all panel regions, put all panes that belong to the current + // region in an array, then render the region. Primarily this ensures that + // the panes are arranged in the proper order. + $content = array(); + foreach ($this->prepared['regions'] as $region_id => $conf) { + $region_panes = array(); + foreach ($conf['pids'] as $pid) { + // Only include panes for region rendering if they had some output. + if (!empty($this->rendered['panes'][$pid])) { + $region_panes[$pid] = $this->rendered['panes'][$pid]; + } + } + $this->rendered['regions'][$region_id] = $this->render_region($region_id, $region_panes); + } + + return $this->rendered['regions']; + } + + /** + * Render a single panel region. + * + * Primarily just a passthrough to the panel region rendering callback + * specified by the style plugin that is attached to the current panel region. + * + * @param $region_id + * The ID of the panel region being rendered + * @param $panes + * An array of panes that are assigned to the panel that's being rendered. + * + * @return string + * The rendered, HTML string output of the passed-in panel region. + */ + function render_region($region_id, $panes) { + $style = $this->prepared['regions'][$region_id]['style']; + $style_settings = $this->prepared['regions'][$region_id]['style settings']; + + // Retrieve the pid (can be a panel page id, a mini panel id, etc.), this + // might be used (or even necessary) for some panel display styles. + // TODO: Got to fix this to use panel page name instead of pid, since pid is + // no longer guaranteed. This needs an API to be able to set the final id. + $owner_id = 0; + if (isset($this->display->owner) && is_object($this->display->owner) && isset($this->display->owner->id)) { + $owner_id = $this->display->owner->id; + } + + return theme($style['render region'], $this->display, $owner_id, $panes, $style_settings, $region_id, $style); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/simple.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/simple.inc new file mode 100644 index 0000000000000000000000000000000000000000..725c28dc35d5e22d0e2d73a550da66d6f9f93c0a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/simple.inc @@ -0,0 +1,11 @@ +<?php +/** + * Create a simple renderer plugin that renders a layout but the content is + * already rendered, not in panes. + */ +$plugin = array( + 'handler' => array( + 'class' => 'panels_renderer_simple', + 'parent' => 'standard', + ), +); \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/single_pane.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/single_pane.inc new file mode 100644 index 0000000000000000000000000000000000000000..67ef61dc02b39eec03e5307bc10657b8cc06e8fa --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/single_pane.inc @@ -0,0 +1,8 @@ +<?php + +$plugin = array( + 'handler' => array( + 'class' => 'panels_renderer_single_pane', + 'parent' => 'standard', + ), +); \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/standard.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/standard.inc new file mode 100644 index 0000000000000000000000000000000000000000..39b235daf8136de276d25548ddf7de227f368812 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/display_renderers/standard.inc @@ -0,0 +1,7 @@ +<?php + +$plugin = array( + 'handler' => array( + 'class' => 'panels_renderer_standard', + ), +); \ No newline at end of file diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/export_ui/panels_layouts.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/export_ui/panels_layouts.inc new file mode 100644 index 0000000000000000000000000000000000000000..94ae5d60ca97e3d45dfd138b2d80dbdc897e2984 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/export_ui/panels_layouts.inc @@ -0,0 +1,24 @@ +<?php + +$plugin = array( + 'schema' => 'panels_layout', + 'access' => 'administer panels layouts', + + 'menu' => array( + 'menu prefix' => 'admin/build/panels', + 'menu item' => 'layouts', + 'menu title' => 'Layouts', + 'menu description' => 'Add, edit or delete custom content layouts.', + ), + + 'title singular' => t('layout'), + 'title singular proper' => t('Layout'), + 'title plural' => t('layouts'), + 'title plural proper' => t('Layouts'), + + 'handler' => array( + 'class' => 'panels_layouts_ui', + 'parent' => 'ctools_export_ui', + ), +); + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/export_ui/panels_layouts_ui.class.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/export_ui/panels_layouts_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..0f47f096b0eace5a83db4144ad5c0d9e5ab0e6e0 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/export_ui/panels_layouts_ui.class.php @@ -0,0 +1,229 @@ +<?php + +class panels_layouts_ui extends ctools_export_ui { + var $lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam egestas congue nibh, vel dictum ante posuere vitae. Cras gravida massa tempor metus eleifend sed elementum tortor scelerisque. Vivamus egestas, tortor quis luctus tristique, sem velit adipiscing risus, et tempus enim felis in massa. Morbi viverra, nisl quis rhoncus imperdiet, turpis massa vestibulum turpis, egestas faucibus nibh metus vel nunc. In hac habitasse platea dictumst. Nunc sit amet nisi quis ipsum tincidunt semper. Donec ac urna enim, et placerat arcu. Morbi eu laoreet justo. Nullam nec velit eu neque mattis pulvinar sed non libero. Sed sed vulputate erat. Fusce sit amet dui nibh."; + + function hook_menu(&$items) { + // During updates, this can run before our schema is set up, so our + // plugin can be empty. + if (empty($this->plugin['menu']['items']['add'])) { + return; + } + + // Change the item to a tab on the Panels page. + $this->plugin['menu']['items']['list callback']['type'] = MENU_LOCAL_TASK; + + // Establish a base for adding plugins + $base = $this->plugin['menu']['items']['add']; + // Remove the default 'add' menu item. + unset($this->plugin['menu']['items']['add']); + + ctools_include('plugins', 'panels'); + $this->builders = panels_get_layout_builders(); + asort($this->builders); + foreach ($this->builders as $name => $builder) { + // Create a new menu item for the builder + $item = $base; + $item['title'] = !empty($builder['builder tab title']) ? $builder['builder tab title'] : 'Add ' . $builder['title']; + $item['page arguments'][] = $name; + $item['path'] = 'add-' . $name; + $this->plugin['menu']['items']['add ' . $name] = $item; + } + + parent::hook_menu($items); + } + + function edit_form(&$form, &$form_state) { + ctools_include('plugins', 'panels'); + // If the plugin is not set, then it should be provided as an argument: + if (!isset($form_state['item']->plugin)) { + $form_state['item']->plugin = $form_state['function args'][2]; + } + + parent::edit_form($form, $form_state); + + $form['category'] = array( + '#type' => 'textfield', + '#title' => t('Category'), + '#description' => t('What category this layout should appear in. If left blank the category will be "Miscellaneous".'), + '#default_value' => $form_state['item']->category, + ); + + ctools_include('context'); + ctools_include('display-edit', 'panels'); + ctools_include('content'); + + // Provide actual layout admin UI here. + // Create a display for editing: + $cache_key = 'builder-' . $form_state['item']->name; + + // Load the display being edited from cache, if possible. + if (!empty($_POST) && is_object($cache = panels_edit_cache_get($cache_key))) { + $display = &$cache->display; + } + else { + $content_types = ctools_content_get_available_types(); + + panels_cache_clear('display', $cache_key); + $cache = new stdClass(); + + $display = panels_new_display(); + $display->did = $form_state['item']->name; + $display->layout = $form_state['item']->plugin; + $display->layout_settings = $form_state['item']->settings; + $display->cache_key = $cache_key; + $display->editing_layout = TRUE; + + $cache->display = $display; + $cache->content_types = $content_types; + $cache->display_title = FALSE; + panels_edit_cache_set($cache); + } + + // Set up lipsum content in all of the existing panel regions: + $display->content = array(); + $display->panels = array(); + $custom = ctools_get_content_type('custom'); + $layout = panels_get_layout($display->layout); + + $regions = panels_get_regions($layout, $display); + foreach ($regions as $id => $title) { + $pane = panels_new_pane('custom', 'custom'); + $pane->pid = $id; + $pane->panel = $id; + $pane->configuration = ctools_content_get_defaults($custom, 'custom'); + $pane->configuration['title'] = 'Lorem Ipsum'; + $pane->configuration['body'] = $this->lipsum; + $display->content[$id] = $pane; + $display->panels[$id] = array($id); + } + + $form_state['display'] = &$display; + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + $form_state['no display settings'] = TRUE; + + $form_state['cache_key'] = $cache_key; + $form_state['content_types'] = $cache->content_types; + $form_state['display_title'] = FALSE; + + $form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display); + $form_state['renderer']->cache = &$cache; + + $form = array_merge($form, panels_edit_display_form($form_state)); + // Make sure the theme will work since our form id is different. + $form['#theme'] = 'panels_edit_display_form'; + + // If we leave the standard submit handler, it'll try to reconcile + // content from the input, but we've not exposed that to the user. This + // makes previews work with the content we forced in. + $form['preview']['button']['#submit'] = array('panels_edit_display_form_preview'); + } + + function edit_form_submit(&$form, &$form_state) { + parent::edit_form_submit($form, $form_state); + $form_state['item']->settings = $form_state['display']->layout_settings; + } + + function list_form(&$form, &$form_state) { + ctools_include('plugins', 'panels'); + $this->builders = panels_get_layout_builders(); + parent::list_form($form, $form_state); + + $categories = $plugins = array('all' => t('- All -')); + foreach ($this->items as $item) { + $categories[$item->category] = $item->category ? $item->category : t('Miscellaneous'); + } + + $form['top row']['category'] = array( + '#type' => 'select', + '#title' => t('Category'), + '#options' => $categories, + '#default_value' => 'all', + '#weight' => -10, + ); + + foreach ($this->builders as $name => $plugin) { + $plugins[$name] = $plugin['title']; + } + + $form['top row']['plugin'] = array( + '#type' => 'select', + '#title' => t('Type'), + '#options' => $plugins, + '#default_value' => 'all', + '#weight' => -9, + ); + } + + function list_filter($form_state, $item) { + if ($form_state['values']['category'] != 'all' && $form_state['values']['category'] != $item->category) { + return TRUE; + } + + if ($form_state['values']['plugin'] != 'all' && $form_state['values']['plugin'] != $item->plugin) { + return TRUE; + } + + return parent::list_filter($form_state, $item); + } + + function list_sort_options() { + return array( + 'disabled' => t('Enabled, title'), + 'title' => t('Title'), + 'name' => t('Name'), + 'category' => t('Category'), + 'storage' => t('Storage'), + 'plugin' => t('Type'), + ); + } + + function list_build_row($item, &$form_state, $operations) { + // Set up sorting + switch ($form_state['values']['order']) { + case 'disabled': + $this->sorts[$item->name] = empty($item->disabled) . $item->admin_title; + break; + case 'title': + $this->sorts[$item->name] = $item->admin_title; + break; + case 'name': + $this->sorts[$item->name] = $item->name; + break; + case 'category': + $this->sorts[$item->name] = ($item->category ? $item->category : t('Miscellaneous')) . $item->admin_title; + break; + case 'plugin': + $this->sorts[$item->name] = $item->plugin; + break; + case 'storage': + $this->sorts[$item->name] = $item->type . $item->admin_title; + break; + } + + $type = !empty($this->builders[$item->plugin]) ? $this->builders[$item->plugin]['title'] : t('Broken/missing plugin'); + $category = $item->category ? check_plain($item->category) : t('Miscellaneous'); + $this->rows[$item->name] = array( + 'data' => array( + array('data' => check_plain($type), 'class' => 'ctools-export-ui-type'), + array('data' => check_plain($item->name), 'class' => 'ctools-export-ui-name'), + array('data' => check_plain($item->admin_title), 'class' => 'ctools-export-ui-title'), + array('data' => $category, 'class' => 'ctools-export-ui-category'), + array('data' => theme('links', $operations), 'class' => 'ctools-export-ui-operations'), + ), + 'title' => check_plain($item->admin_description), + 'class' => !empty($item->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled', + ); + } + + function list_table_header() { + return array( + array('data' => t('Type'), 'class' => 'ctools-export-ui-type'), + array('data' => t('Name'), 'class' => 'ctools-export-ui-name'), + array('data' => t('Title'), 'class' => 'ctools-export-ui-title'), + array('data' => t('Category'), 'class' => 'ctools-export-ui-category'), + array('data' => t('Operations'), 'class' => 'ctools-export-ui-operations'), + ); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible-admin.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible-admin.css new file mode 100644 index 0000000000000000000000000000000000000000..744e46e9974fd3aa38dfc34b106461ff02f8a6c4 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible-admin.css @@ -0,0 +1,87 @@ + +#panels-dnd-main .panel-flexible-edit-layout div.panels-display .pane-add-link, +.panel-flexible-edit-layout .panel-pane { + display: none; +} + +.panel-flexible-edit-layout div.panels-display h2.label { + padding-right: 0; +} + +.panel-flexible-edit-layout .panels-flexible-column-inside { +/* margin: 5px; */ + border: 1px dotted green; +} + +.panels-flexible-column-inside { +/* overflow: hidden; */ +} + +.panel-flexible-edit-layout .panels-flexible-column > .flexible-title { + color: green; +} + +.panel-flexible-edit-layout .panels-flexible-row-inside { + margin: 5px; + border: 1px dotted blue; +} + +.panel-flexible-edit-layout .panels-flexible-row > .flexible-title { + color: blue; +} + +.panel-flexible-no-edit-layout .flexible-layout-only { + display: none; +} + +.panel-flexible-edit-layout .flexible-title { + text-align: center; + width: 5em; + margin-left: auto; + margin-right: auto; +} + +.panel-flexible-no-edit-layout .panels-flexible-splitter { + display: none; +} + +.panels-flexible-splitter span { + display: none; +} + +.panels-flexible-splitter { + width: 11px; + float: left; + margin-left: -7px; + margin-right: -6px; + cursor: e-resize; /* in case col-resize isn't supported */ + cursor: col-resize; + height: 30px; + position: relative; + z-index: 1; + background: url(grippie-vertical.png) center center no-repeat #eee; + border: 1px solid #ccc; +} + +.flexible-splitting { + border: 2px dotted yellow !important; + margin: -2px !important; +} + +.flexible-splitter-hover-box { + position: absolute; + z-index: 1000; + background: white; + color: black; + border: 1px solid black; + width: 60px; + height: 2em; + text-align: center; + line-height: 2em; +} + +#panels-edit-display .panel-pane, +#panels-edit-display .helperclass { + margin: .5em; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible-admin.js b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible-admin.js new file mode 100644 index 0000000000000000000000000000000000000000..e8b3cc627b5955681ff2541cbaacf3ed32a5b5fe --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible-admin.js @@ -0,0 +1,408 @@ + +Drupal.flexible = Drupal.flexible || {}; + +Drupal.flexible.splitters = []; + +/** + * Fix the height of all splitters to be the same as the items they are + * splitting. + */ +Drupal.flexible.fixHeight = function() { + for (i in Drupal.flexible.splitters) { + Drupal.flexible.splitters[i].fixHeight(); + } +} + +Drupal.behaviors.flexibleAdmin = function(context) { + // Show/hide layout manager button + $('input#panels-flexible-toggle-layout:not(.panels-flexible-processed)', context) + .addClass('panels-flexible-processed') + .click(function() { + $('.panel-flexible-admin') + .toggleClass('panel-flexible-no-edit-layout') + .toggleClass('panel-flexible-edit-layout'); + + if ($('.panel-flexible-admin').hasClass('panel-flexible-edit-layout')) { + $(this).val(Drupal.t('Hide layout designer')); + Drupal.flexible.fixHeight(); + } + else { + $(this).val(Drupal.t('Show layout designer')); + } + return false; + }); + + // Window splitter behavior. + $('div.panels-flexible-splitter:not(.panels-splitter-processed)', context) + .addClass('panels-splitter-processed') + .each(function() { + Drupal.flexible.splitters.push(new Drupal.flexible.splitter($(this))); + }); + + // Sometimes the splitter IS the context and the above syntax won't + // catch that. + if ($(context).hasClass('panels-flexible-splitter')) { + $(context) + .addClass('panels-splitter-processed') + .each(function() { + Drupal.flexible.splitters.push(new Drupal.flexible.splitter($(this))); + }); + } + + Drupal.flexible.fixHeight(); +}; + +Drupal.flexible.splitter = function($splitter) { + var splitter = this; + + this.fixHeight = function() { + // Set the splitter height to the shorter of the two: + $splitter.height(Math.max(this.left.outerHeight(), this.right.outerHeight())); + } + + function splitterStart(event) { + // Show splitting classes. +// splitter.left.addClass('flexible-splitting'); // Safari selects A/B text on a move +// splitter.right.addClass('flexible-splitting'); // Safari selects A/B text on a move +// splitter.splitter.addClass('flexible-splitter-splitting'); + + // Bind motion events. + $(document) + .bind("mousemove", splitterMove) + .bind("mouseup", splitterEnd); + + // Calculate some data about our split regions: + splitter.getSizes(); + + // The X coordinate where we clicked. + splitter.startX = event.pageX; + + // The current sizes of the left/right panes. + splitter.currentLeft = parseFloat(splitter.left_width) * parseFloat(splitter.left_scale); + splitter.currentRight = parseFloat(splitter.right_width) * parseFloat(splitter.right_scale); + + // The starting sizes of the left right panes. + splitter.startLeft = splitter.currentLeft; + splitter.startRight = splitter.currentRight; + + if (splitter.left_width_type == splitter.right_width_type) { + // If they're the same type, add the two together so we know how + // much space we have for splitting. + splitter.max = splitter.startLeft + splitter.startRight; + + // calculate unit size and min/max width. + if (splitter.left_width_type == '%') { + splitter.left_total = splitter.left.width() / (splitter.left_width / 100); + // One pixel is equivalent to what percentage of the total? + splitter.left_unit = (1 / splitter.left_total) * 100; + splitter.left_min = 5; // minimum % we'll use. + } + else { + splitter.left_unit = 1; + splitter.left_min = 25; // minimum pixels we'll use. + } + if (splitter.right_width_type == '%') { + splitter.right_total = splitter.right.width() / (splitter.right_width / 100); + // One pixel is equivalent to what percentage of the total? + splitter.right_unit = (1 / splitter.right_total) * 100; + splitter.right_min = 5; // minimum % we'll use. + } + else { + splitter.right_unit = 1; + splitter.right_min = 25; // minimum pixels we'll use. + } + } + else { + // Figure out the parent blob's width and set the max to that + splitter.parent = $splitter.parent().parent(); + + if (splitter.left_width_type != 'px') { + // Only the 'px' side can resize. + splitter.left_unit = 0; + splitter.right_unit = 1; + splitter.right_min = 25; + splitter.right_padding = parseInt(splitter.parent.css('padding-right')); + splitter.right_parent = parseInt(splitter.right.parent().css('margin-right')); + splitter.max = splitter.right.width() + splitter.left.parent().width() - + (splitter.left.siblings(':not(.panels-flexible-splitter)').length * 25) - 25; + } + else { + splitter.right_unit = 0; + splitter.left_unit = 1; + splitter.left_min = 25; + splitter.left_padding = parseInt(splitter.parent.css('padding-left')); + splitter.left_parent = parseInt(splitter.left.parent().css('margin-left')); + if (splitter.right_id) { + splitter.max = splitter.left.width() + splitter.right.parent().width() - + (splitter.right.siblings(':not(.panels-flexible-splitter)').length * 25) - 25; + } + else { + var subtract = 0; + splitter.left.siblings(':not(.panels-flexible-splitter)').each(function() { subtract += $(this).width()}); + splitter.max = splitter.left.parent().width() - subtract; + } + } + } + + var offset = $(splitter.splitter).offset(); + + // Create boxes to display widths left and right of the mouse pointer. + // Create left box only if left box is mobile. + if (splitter.left_unit) { + splitter.left_box = $('<div class="flexible-splitter-hover-box"> </div>'); + $('body').append(splitter.left_box); + splitter.left_box.css('top', offset.top); + splitter.left_box.css('left', event.pageX - 65); + + if (splitter.left_width_type == '%') { + var left = splitter.currentLeft / splitter.left_scale; + splitter.left_box.html(left.toFixed(2) + splitter.left_width_type); + } + else { + // make sure pixel values are always whole integers. + splitter.currentLeft = parseInt(splitter.currentLeft); + splitter.left_box.html(splitter.currentLeft + splitter.left_width_type); + } + } + + // Create the right box if the right side is mobile. + if (splitter.right_unit) { + splitter.right_box = $('<div class="flexible-splitter-hover-box"></div>'); + $('body').append(splitter.right_box); + splitter.right_box.css('top', offset.top); + splitter.right_box.css('left', event.pageX + 5); + if (splitter.right_width_type == '%') { + var right = splitter.currentRight / splitter.right_scale; + splitter.right_box.html(right.toFixed(2) + splitter.right_width_type); + } + else { + // make sure pixel values are always whole integers. + splitter.currentRight = parseInt(splitter.currentRight); + splitter.right_box.html(splitter.currentRight + splitter.right_width_type); + } + } + + return false; + }; + + function splitterMove(event) { + var diff = splitter.startX - event.pageX; + var moved = 0; + // Bah, javascript has no logical xor operator + if ((splitter.left_unit && !splitter.right_unit) || + (!splitter.left_unit && splitter.right_unit)) { + // This happens when one side is fixed and the other side is fluid. The + // fixed side actually adjusts while the fluid side does not. However, + // in order to move the fluid side we have to adjust the padding + // on our parent object. + if (splitter.left_unit) { + // Only the left box is allowed to move. + splitter.currentLeft = splitter.startLeft - diff; + + if (splitter.currentLeft < splitter.left_min) { + splitter.currentLeft = splitter.left_min; + } + if (splitter.currentLeft > splitter.max) { + splitter.currentLeft = splitter.max; + } + + // If the shift key is pressed, go with 1% or 10px boundaries. + if (event.shiftKey) { + splitter.currentLeft = parseInt(splitter.currentLeft / 10) * 10; + } + moved = (splitter.startLeft - splitter.currentLeft); + } + else { + // Only the left box is allowed to move. + splitter.currentRight = splitter.startRight + diff; + + if (splitter.currentRight < splitter.right_min) { + splitter.currentRight = splitter.right_min; + } + if (splitter.currentRight > splitter.max) { + splitter.currentRight = splitter.max; + } + + // If the shift key is pressed, go with 1% or 10px boundaries. + if (event.shiftKey) { + splitter.currentRight = parseInt(splitter.currentRight / 10) * 10; + } + moved = (splitter.currentRight - splitter.startRight); + } + } + else { + // If they are both the same type, do this.. + // Adjust the left side by the amount we moved. + var left = -1 * diff * splitter.left_unit; + + splitter.currentLeft = splitter.startLeft + left; + + if (splitter.currentLeft < splitter.left_min) { + splitter.currentLeft = splitter.left_min; + } + if (splitter.currentLeft > splitter.max - splitter.right_min) { + splitter.currentLeft = splitter.max - splitter.right_min; + } + + // If the shift key is pressed, go with 1% or 10px boundaries. + if (event.shiftKey) { + if (splitter.left_width_type == '%') { + splitter.currentLeft = parseInt(splitter.currentLeft / splitter.left_scale) * splitter.left_scale; + } + else { + splitter.currentLeft = parseInt(splitter.currentLeft / 10) * 10; + } + } + + // Now automatically make the right side to be the other half. + splitter.currentRight = splitter.max - splitter.currentLeft; + + // recalculate how far we've moved into pixels so we can adjust our visible + // boxes. + moved = (splitter.startLeft - splitter.currentLeft) / splitter.left_unit; + } + + if (splitter.left_unit) { + splitter.left_box.css('left', splitter.startX - 65 - moved); + if (splitter.left_width_type == '%') { + var left = splitter.currentLeft / splitter.left_scale; + splitter.left_box.html(left.toFixed(2) + splitter.left_width_type); + } + else { + splitter.left_box.html(parseInt(splitter.currentLeft) + splitter.left_width_type); + } + + // Finally actually move the left side + splitter.left.css('width', splitter.currentLeft + splitter.left_width_type); + } + else { + // if not moving the left side, adjust the parent padding instead. + splitter.parent.css('padding-right', (splitter.right_padding + moved) + 'px'); + splitter.right.parent().css('margin-right', (splitter.right_parent - moved) + 'px'); + } + + if (splitter.right_unit) { + splitter.right_box.css('left', splitter.startX + 5 - moved); + if (splitter.right_width_type == '%') { + var right = splitter.currentRight / splitter.right_scale; + splitter.right_box.html(right.toFixed(2) + splitter.right_width_type); + } + else { + splitter.right_box.html(parseInt(splitter.currentRight) + splitter.right_width_type); + } + + // Finally actually move the right side + splitter.right.css('width', splitter.currentRight + splitter.right_width_type); + } + else { + // if not moving the right side, adjust the parent padding instead. + splitter.parent.css('padding-left', (splitter.left_padding - moved) + 'px'); + splitter.left.parent().css('margin-left', (splitter.left_parent + moved) + 'px'); + if (jQuery.browser.msie) { + splitter.left.parent().css('left', splitter.currentLeft); + } + } + return false; + }; + + function splitterEnd(event) { + if (splitter.left_unit) { + splitter.left_box.remove(); + } + + if (splitter.right_unit) { + splitter.right_box.remove(); + } + + splitter.left.removeClass("flexible-splitting"); // Safari selects A/B text on a move + splitter.right.removeClass("flexible-splitting"); // Safari selects A/B text on a move + splitter.splitter.removeClass("flexible-splitter-splitting"); // Safari selects A/B text on a move + splitter.left.css("-webkit-user-select", "text"); // let Safari select text again + splitter.right.css("-webkit-user-select", "text"); // let Safari select text again + + if (splitter.left_unit) { + splitter.left_width = splitter.currentLeft / parseFloat(splitter.left_scale); + } + + if (splitter.right_unit) { + splitter.right_width = splitter.currentRight / parseFloat(splitter.right_scale); + } + + splitter.putSizes(); + Drupal.flexible.fixHeight(); + + $(document) + .unbind("mousemove", splitterMove) + .unbind("mouseup", splitterEnd); + + // Store the data on the server. + $.ajax({ + type: "POST", + url: Drupal.settings.flexible.resize, + data: { + 'left': splitter.left_id, + 'left_width': splitter.left_width, + 'right': splitter.right_id, + 'right_width': splitter.right_width + }, + global: true, + success: Drupal.CTools.AJAX.respond, + error: function() { + alert("An error occurred while attempting to process " + Drupal.settings.flexible.resize); + }, + dataType: 'json' + }); + }; + + this.getSizes = function() { + splitter.left_width = $splitter.children('.panels-flexible-splitter-left-width').html(); + splitter.left_scale = $splitter.children('.panels-flexible-splitter-left-scale').html(); + splitter.left_width_type = $splitter.children('.panels-flexible-splitter-left-width-type').html(); + splitter.right_width = $splitter.children('.panels-flexible-splitter-right-width').html(); + splitter.right_scale = $splitter.children('.panels-flexible-splitter-right-scale').html(); + splitter.right_width_type = $splitter.children('.panels-flexible-splitter-right-width-type').html(); + }; + + this.putSizes = function() { + $(splitter.left_class + '-width').html(splitter.left_width); + if (splitter.left_class != splitter.right_class) { + $(splitter.right_class + '-width').html(splitter.right_width); + } + } + + splitter.splitter = $splitter; + splitter.left_class = $splitter.children('.panels-flexible-splitter-left').html(); + splitter.left_id = $splitter.children('.panels-flexible-splitter-left-id').html(); + splitter.left = $(splitter.left_class); + splitter.right_class = $splitter.children('.panels-flexible-splitter-right').html(); + splitter.right_id = $splitter.children('.panels-flexible-splitter-right-id').html(); + splitter.right = $(splitter.right_class); + + $splitter + .bind("mousedown", splitterStart); + +}; + +/** + * Provide an AJAX response command to allow the server to request + * height fixing. + */ +Drupal.CTools.AJAX.commands.flexible_fix_height = function() { + Drupal.flexible.fixHeight(); +}; + +/** + * Provide an AJAX response command to fix the first/last bits of a + * group. + */ +Drupal.CTools.AJAX.commands.flexible_fix_firstlast = function(data) { + $(data.selector + ' > div > .' + data.base) + .removeClass(data.base + '-first') + .removeClass(data.base + '-last'); + + $(data.selector + ' > div > .' + data.base + ':first') + .addClass(data.base + '-first'); + $(data.selector + ' > div > .' + data.base + ':last') + .addClass(data.base + '-last'); +}; + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.css new file mode 100644 index 0000000000000000000000000000000000000000..0d1fbe631d33b4e40171844c45af2a43f794ed7e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.css @@ -0,0 +1,4 @@ + +.panel-flexible .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.inc new file mode 100644 index 0000000000000000000000000000000000000000..320745afdf16f4c408f15df4282f27d35dd3c729 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.inc @@ -0,0 +1,1766 @@ +<?php + +/** + * Implementation of hook_panels_layouts() + */ +// Plugin definition +$plugin = array( + 'title' => t('Flexible'), + 'category' => t('Builders'), + 'icon' => 'flexible.png', + 'theme' => 'panels_flexible', + 'admin theme' => 'panels_flexible_admin', + 'css' => 'flexible.css', + 'admin css' => 'flexible-admin.css', + 'settings form' => 'panels_flexible_settings_form', + 'settings submit' => 'panels_flexible_settings_submit', + 'settings validate' => 'panels_flexible_settings_validate', + 'panels function' => 'panels_flexible_panels', + 'hook menu' => 'panels_flexible_menu', + + // Reuisable layout Builder specific directives + 'builder' => TRUE, + 'builder tab title' => 'Add flexible layout', // menu so translated elsewhere + + 'get child' => 'panels_flexible_get_sublayout', + 'get children' => 'panels_flexible_get_sublayouts', + + // Define ajax callbacks + 'ajax' => array( + 'settings' => 'panels_ajax_flexible_edit_settings', + 'add' => 'panels_ajax_flexible_edit_add', + 'remove' => 'panels_ajax_flexible_edit_remove', + 'resize' => 'panels_ajax_flexible_edit_resize', + 'reuse' => 'panels_ajax_flexible_edit_reuse', + ), +); + +/** + * Merge the main flexible plugin with a layout to create a sub plugin. + * + * This is used for both panels_flexible_get_sublayout and + * panels_flexible_get_sublayouts. + */ +function panels_flexible_merge_plugin($plugin, $layout) { + $plugin['name'] = 'flexible:' . $layout->name; + $plugin['category'] = !empty($layout->category) ? check_plain($layout->category) : t('Miscellaneous'); + $plugin['title'] = check_plain($layout->admin_title); + $plugin['description'] = check_plain($layout->admin_description); + $plugin['layout'] = $layout; + $plugin['builder'] = FALSE; + $plugin['builder tab title'] = NULL; + return $plugin; +} + +/** + * Callback to provide a single stored flexible layout. + */ +function panels_flexible_get_sublayout($plugin, $layout_name, $sublayout_name) { + // Do not worry about caching; Panels is handling that for us. + ctools_include('export'); + $item = ctools_export_crud_load('panels_layout', $sublayout_name); + if ($item) { + return panels_flexible_merge_plugin($plugin, $item); + } +} + +/** + * Callback to provide all stored flexible layouts. + */ +function panels_flexible_get_sublayouts($plugin, $layout_name) { + $layouts[$layout_name] = $plugin; + ctools_include('export'); + $items = ctools_export_load_object('panels_layout', 'conditions', array('plugin' => 'flexible')); + foreach ($items as $name => $item) { + $layouts['flexible:' . $name] = panels_flexible_merge_plugin($plugin, $item); + } + + return $layouts; +} + +/** + * Convert settings from old style to new, or provide defaults for + * empty settings. + * @param <type> $settings + */ +function panels_flexible_convert_settings(&$settings, &$layout) { + // This indicates that this is a layout that they used the checkbox + // on. The layout is still 'flexible' but it's actually pointing + // to another stored one and we have to load it. + if (!empty($settings['layout'])) { + $layout = panels_get_layout('flexible:' . $settings['layout']); + } + + if (!empty($layout['layout'])) { + $settings = $layout['layout']->settings; + if ($settings) { + return $settings; + } + } + + if (empty($settings)) { + // set up a default + $settings = array( + 'items' => array( + // The 'canvas' is a special row that does not get rendered + // normally, but is used to contain the columns. + 'canvas' => array( + 'type' => 'row', + 'contains' => 'column', + 'children' => array('main'), + 'parent' => NULL, + ), + 'main' => array( + 'type' => 'column', + 'width' => 100, + 'width_type' => '%', + 'children' => array('main-row'), + 'parent' => 'canvas', + ), + 'main-row' => array( + 'type' => 'row', + 'contains' => 'region', + 'children' => array('center'), + 'parent' => 'main', + ), + 'center' => array( + 'type' => 'region', + 'title' => t('Center'), + 'width' => 100, + 'width_type' => '%', + 'parent' => 'main-row', + ), + ), + ); + } + else if (!isset($settings['items'])) { + // Convert an old style flexible to a new style flexible. + $old = $settings; + $settings = array(); + $settings['items']['canvas'] = array( + 'type' => 'row', + 'contains' => 'column', + 'children' => array(), + 'parent' => NULL, + ); + // add the left sidebar column, row and region if it exists. + if (!empty($old['sidebars']['left'])) { + $settings['items']['canvas']['children'][] = 'sidebar-left'; + $settings['items']['sidebar-left'] = array( + 'type' => 'column', + 'width' => $old['sidebars']['left_width'], + 'width_type' => $old['sidebars']['width_type'], + 'children' => array('sidebar-left-row'), + 'parent' => 'canvas', + ); + $settings['items']['sidebar-left-row'] = array( + 'type' => 'row', + 'contains' => 'region', + 'children' => array('sidebar_left'), + 'parent' => 'sidebar-left', + ); + $settings['items']['sidebar_left'] = array( + 'type' => 'region', + 'title' => t('Left sidebar'), + 'width' => 100, + 'width_type' => '%', + 'parent' => 'sidebar-left-row', + ); + } + + $settings['items']['canvas']['children'][] = 'main'; + + if (!empty($old['sidebars']['right'])) { + $settings['items']['canvas']['children'][] = 'sidebar-right'; + $settings['items']['sidebar-right'] = array( + 'type' => 'column', + 'width' => $old['sidebars']['right_width'], + 'width_type' => $old['sidebars']['width_type'], + 'children' => array('sidebar-right-row'), + 'parent' => 'canvas', + ); + $settings['items']['sidebar-right-row'] = array( + 'type' => 'row', + 'contains' => 'region', + 'children' => array('sidebar_right'), + 'parent' => 'sidebar-right', + ); + $settings['items']['sidebar_right'] = array( + 'type' => 'region', + 'title' => t('Right sidebar'), + 'width' => 100, + 'width_type' => '%', + 'parent' => 'sidebar-right-row', + ); + } + + // Add the main column. + $settings['items']['main'] = array( + 'type' => 'column', + 'width' => 100, + 'width_type' => '%', + 'children' => array(), + 'parent' => 'canvas', + ); + + // Add rows and regions. + for ($row = 1; $row <= intval($old['rows']); $row++) { + // Create entry for the row + $settings['items']["row_$row"] = array( + 'type' => 'row', + 'contains' => 'region', + 'children' => array(), + 'parent' => 'main', + ); + // Add the row to the parent's children + $settings['items']['main']['children'][] = "row_$row"; + + for ($col = 1; $col <= intval($old["row_$row"]['columns']); $col++) { + // Create entry for the region + $settings['items']["row_${row}_$col"] = array( + 'type' => 'region', + 'width' => $old["row_$row"]["width_$col"], + 'width_type' => '%', + 'parent' => "row_$row", + ); + // Add entry for the region to the row's children + $settings['items']["row_$row"]['children'][] = "row_${row}_$col"; + + // Apply the proper title to the region + if (!empty($old["row_$row"]['names'][$col - 1])) { + $settings['items']["row_${row}_$col"]['title'] = $old["row_$row"]['names'][$col - 1]; + } + else { + $settings['items']["row_${row}_$col"]['title'] = t("Row @row, Column @col", array('@row' => $row, '@col' => $col)); + } + } + } + } + else if (isset($settings['canvas'])) { + // Convert the old 'canvas' to the new canvas row. + $settings['items']['canvas'] = array( + 'type' => 'row', + 'contains' => 'column', + 'children' => $settings['canvas'], + 'parent' => NULL, + ); + unset($settings['canvas']); + } +} + +/** + * Define the actual list of columns and rows for this flexible panel. + */ +function panels_flexible_panels($display, $settings, $layout) { + $items = array(); + panels_flexible_convert_settings($settings, $layout); + foreach ($settings['items'] as $id => $item) { + if ($item['type'] == 'region') { + $items[$id] = $item['title']; + } + } + + return $items; +} + +/** + * Create a renderer object. + * + * The renderer object contains data that is passed around from function + * to function allowing us to render our CSS and HTML easily. + * + * @todo Convert the functions to methods and make this properly OO. + */ +function panels_flexible_create_renderer($admin, $id, $content, $settings, &$display, $layout, $handler) { + $renderer = new stdClass; + $renderer->settings = $settings; + $renderer->content = $content; + $renderer->css_id = $id; + $renderer->did = &$display->did; + if ($admin) { + // always scale in admin mode. + $renderer->scale_base = 99.0; + } + else { + $renderer->scale_base = !empty($settings['items']['canvas']['no_scale']) ? 100.0 : 99.0; + } + $renderer->id_str = $id ? 'id="' . $id . '"' : ''; + $renderer->admin = $admin; + $renderer->handler = $handler; + + // Set up basic classes for all of our components. + $renderer->name = !empty($layout['layout']) ? $layout['layout']->name : $display->did; + $renderer->base_class = $renderer->name; + $renderer->item_class['column'] = 'panels-flexible-column'; + $renderer->item_class['row'] = 'panels-flexible-row'; + $renderer->item_class['region'] = 'panels-flexible-region'; + $renderer->base['canvas'] = 'panels-flexible-' . $renderer->base_class; + + // Override these if selected from the UI and not in admin mode. + if (!$admin) { + if (!empty($settings['items']['canvas']['class'])) { + $renderer->base_class = $settings['items']['canvas']['class']; + $renderer->base['canvas'] = $renderer->base_class; + } + if (!empty($settings['items']['canvas']['column_class'])) { + $renderer->item_class['column'] = $settings['items']['canvas']['column_class']; + } + if (!empty($settings['items']['canvas']['row_class'])) { + $renderer->item_class['row'] = $settings['items']['canvas']['row_class']; + } + if (!empty($settings['items']['canvas']['region_class'])) { + $renderer->item_class['region'] = $settings['items']['canvas']['region_class']; + } + } + + // Get the separation values out of the canvas settings. + $renderer->column_separation = !empty($settings['items']['canvas']['column_separation']) ? $settings['items']['canvas']['column_separation'] : '0.5em'; + + $renderer->region_separation = !empty($settings['items']['canvas']['region_separation']) ? $settings['items']['canvas']['region_separation'] : '0.5em'; + + $renderer->row_separation = !empty($settings['items']['canvas']['row_separation']) ? $settings['items']['canvas']['row_separation'] : '0.5em'; + + // Make some appended classes so it's easier to reference them. + + $renderer->base['column'] = $renderer->item_class['column'] . '-' . $renderer->base_class; + $renderer->base['row'] = $renderer->item_class['row'] . '-' . $renderer->base_class; + $renderer->base['region'] = $renderer->item_class['region'] . '-' . $renderer->base_class; + + if ($renderer->name != 'new') { + // Use v2 to guarantee all CSS gets regenerated to account for changes in + // how some divs will be rendered. + $renderer->css_cache_name = 'flexiblev2:' . $renderer->name; + if ($admin) { + ctools_include('css'); + ctools_css_clear($renderer->css_cache_name); + } + } + return $renderer; +} + +/** + * Draw the flexible layout. + */ +function theme_panels_flexible($id, $content, $settings, $display, $layout, $handler) { + panels_flexible_convert_settings($settings, $layout); + + $renderer = panels_flexible_create_renderer(FALSE, $id, $content, $settings, $display, $layout, $handler); + + // CSS must be generated because it reports back left/middle/right + // positions. + $css = panels_flexible_render_css($renderer); + + if (!empty($renderer->css_cache_name) && empty($display->editing_layout)) { + ctools_include('css'); + // Generate an id based upon rows + columns: + $filename = ctools_css_retrieve($renderer->css_cache_name); + if (!$filename) { + $filename = ctools_css_store($renderer->css_cache_name, $css, FALSE); + } + + // Give the CSS to the renderer to put where it wants. + if ($handler) { + $handler->add_css($filename, 'module', 'all', FALSE); + } + else { + ctools_css_add_css($filename, 'module', 'all', FALSE); + } + } + else { + // If the id is 'new' we can't reliably cache the CSS in the filesystem + // because the display does not truly exist, so we'll stick it in the + // head tag. We also do this if we've been told we're in the layout + // editor so that it always gets fresh CSS. + drupal_set_html_head("<style type=\"text/css\">\n$css</style>\n"); + } + + // Also store the CSS on the display in case the live preview or something + // needs it + $display->add_css = $css; + + $output = "<div class=\"panel-flexible " . $renderer->base['canvas'] . " clear-block\" $renderer->id_str>\n"; + $output .= "<div class=\"panel-flexible-inside " . $renderer->base['canvas'] . "-inside\">\n"; + + $output .= panels_flexible_render_items($renderer, $settings['items']['canvas']['children'], $renderer->base['canvas']); + + // Wrap the whole thing up nice and snug + $output .= "</div>\n</div>\n"; + + return $output; +} + +/** + * Draw the flexible layout. + */ +function theme_panels_flexible_admin($id, $content, $settings, $display, $layout, $handler) { + // We never draw stored flexible layouts in admin mode; they must be edited + // from the stored layout UI at that point. + if (!empty($layout['layout'])) { + return theme_panels_flexible($id, $content, $settings, $display, $layout, $handler); + } + + panels_flexible_convert_settings($settings, $layout); + $renderer = panels_flexible_create_renderer(TRUE, $id, $content, $settings, $display, $layout, $handler); + + $css = panels_flexible_render_css($renderer); + + // For the administrative view, add CSS directly to head. + drupal_set_html_head("<style type=\"text/css\">\n$css</style>\n"); + + if (empty($display->editing_layout)) { + $output = '<input type="submit" id="panels-flexible-toggle-layout" value ="' . + t('Show layout designer') . '">'; + if (user_access('administer panels layouts')) { + $output .= '<input type="hidden" class="panels-flexible-reuse-layout-url" value="' . url($handler->get_url('layout', 'reuse'), array('absolute' => TRUE)) . '">'; + $output .= '<input type="submit" id="panels-flexible-reuse-layout" class="ctools-use-modal" value ="' . + t('Reuse layout') . '">'; + } + $output .= "<div class=\"panel-flexible " . $renderer->base['canvas'] . " clear-block panel-flexible-admin panel-flexible-no-edit-layout\" $renderer->id_str>\n"; + } + else { + $output = "<div class=\"panel-flexible " . $renderer->base['canvas'] . " clear-block panel-flexible-admin panel-flexible-edit-layout\" $renderer->id_str>\n"; + } + $output .= "<div class=\"panel-flexible-inside " . $renderer->base['canvas'] . "-inside \">\n"; + + $content = panels_flexible_render_items($renderer, $settings['items']['canvas']['children'], $renderer->base['row'] . '-canvas'); + $output .= panels_flexible_render_item($renderer, $settings['items']['canvas'], $content, 'canvas', 0, 0, TRUE); + + // Wrap the whole thing up nice and snug + $output .= "</div>\n</div>\n"; + + drupal_add_js($layout['path'] . '/flexible-admin.js'); + drupal_add_js(array('flexible' => array('resize' => url($handler->get_url('layout', 'resize'), array('absolute' => TRUE)))), 'setting'); + return $output; +} + +/** + * Render a piece of a flexible layout. + */ +function panels_flexible_render_items($renderer, $list, $owner_id) { + $output = ''; + $groups = array('left' => '', 'middle' => '', 'right' => ''); + $max = count($list) - 1; + $prev = NULL; + + foreach ($list as $position => $id) { + $item = $renderer->settings['items'][$id]; + $location = isset($renderer->positions[$id]) ? $renderer->positions[$id] : 'middle'; + + if ($renderer->admin && $item['type'] != 'row' && $prev ) { + $groups[$location] .= panels_flexible_render_splitter($renderer, $prev, $id); + } + + switch ($item['type']) { + case 'column': + $content = panels_flexible_render_items($renderer, $item['children'], $renderer->base['column'] . '-' . $id); + $groups[$location] .= panels_flexible_render_item($renderer, $item, $content, $id, $position, $max); + break; + case 'row': + $content = panels_flexible_render_items($renderer, $item['children'], $renderer->base['row'] . '-' . $id); + $groups[$location] .= panels_flexible_render_item($renderer, $item, $content, $id, $position, $max, TRUE); + break; + case 'region': + $content = isset($renderer->content[$id]) ? $renderer->content[$id] : " "; + $groups[$location] .= panels_flexible_render_item($renderer, $item, $content, $id, $position, $max); + break; + } + + // If all items are fixed then we have a special splitter on the right to + // control the overall width. + if (!empty($renderer->admin) && $max == $position && $location == 'left') { + $groups[$location] .= panels_flexible_render_splitter($renderer, $id, NULL); + } + $prev = $id; + } + + $group_count = count(array_filter($groups)); + + // Render each group. We only render the group div if we're in admin mode + // or if there are multiple groups. + foreach ($groups as $position => $content) { + if (!empty($content) || $renderer->admin) { + if ($group_count > 1 || $renderer->admin) { + $output .= '<div class="' . $owner_id . '-' . $position . '">' . $content . '</div>'; + } + else { + $output .= $content; + } + } + } + + return $output; +} + +/** + * Render a column in the flexible layout. + */ +function panels_flexible_render_item($renderer, $item, $content, $id, $position, $max, $clear = FALSE) { + + // If we are rendering a row and there is just one row, we don't need to + // render the row unless there is fixed_width content inside it. + if (empty($renderer->admin) && $item['type'] == 'row' && $max == 0) { + $fixed = FALSE; + foreach ($item['children'] as $id) { + if ($renderer->settings['items'][$id]['width_type'] != '%') { + $fixed = TRUE; + break; + } + } + + if (!$fixed) { + return $content; + } + } + + // If we are rendering a column and there is just one column, we don't + // need to render the column unless it has a fixed_width. + if (empty($renderer->admin) && $item['type'] == 'column' && $max == 0 && $item['width_type'] == '%') { + return $content; + } + + $base = $renderer->item_class[$item['type']]; + $output = '<div class="' . $base . ' ' . $renderer->base[$item['type']] . '-' . $id; + if ($position == 0) { + $output .= ' ' . $base . '-first'; + } + if ($position == $max) { + $output .= ' ' . $base . '-last'; + } + if ($clear) { + $output .= ' clear-block'; + } + + if (isset($item['class'])) { + $output .= ' ' . check_plain($item['class']); + } + + $output .= '">' . "\n"; + + if (!empty($renderer->admin)) { + $output .= panels_flexible_render_item_links($renderer, $id, $item); + } + + $output .= ' <div class="inside ' . $base . '-inside ' . $base . '-' . $renderer->base_class . '-' . $id . '-inside'; + if ($position == 0) { + $output .= ' ' . $base . '-inside-first'; + } + if ($position == $max) { + $output .= ' ' . $base . '-inside-last'; + } + if ($clear) { + $output .= ' clear-block'; + } + + $output .= "\">\n"; + $output .= $content; + $output .= ' </div>' . "\n"; + $output .= '</div>' . "\n"; + + return $output; +} +/** + * Render a splitter div to place between the $left and $right items. + * + * If the right ID is NULL that means there isn't actually a box to the + * right, but we need a splitter anyway. We'll mostly use info about the + * left, but pretend it's 'fluid' so that the javascript won't actually + * modify the right item. + */ +function panels_flexible_render_splitter($renderer, $left_id, $right_id) { + $left = $renderer->settings['items'][$left_id]; + + $left_class = $renderer->base[$left['type']] . '-' . $left_id; + if ($right_id) { + $right = $renderer->settings['items'][$right_id]; + $right_class = $renderer->base[$left['type']] . '-' . $right_id; + } + else { + $right = $left; + $right_class = $left_class; + } + + $output = '<div class="panels-flexible-splitter flexible-splitter-for-' . $left_class . '">'; + + // Name the left object + $output .= '<span class="panels-flexible-splitter-left">'; + $output .= '.' . $left_class; + $output .= '</span>'; + + $output .= '<span class="panels-flexible-splitter-left-id">'; + $output .= $left_id; + $output .= '</span>'; + + $output .= '<span class="panels-flexible-splitter-left-width ' . $left_class . '-width">'; + $output .= $left['width']; + $output .= '</span>'; + + $output .= '<span class="panels-flexible-splitter-left-scale">'; + $output .= isset($renderer->scale[$left_id]) ? $renderer->scale[$left_id] : 1; + $output .= '</span>'; + + $output .= '<span class="panels-flexible-splitter-left-width-type">'; + $output .= $left['width_type']; + $output .= '</span>'; + + // Name the right object + $output .= '<span class="panels-flexible-splitter-right">'; + $output .= '.' . $right_class; + $output .= '</span>'; + + $output .= '<span class="panels-flexible-splitter-right-id">'; + $output .= $right_id; + $output .= '</span>'; + + $output .= '<span class="panels-flexible-splitter-right-width ' . $right_class . '-width">'; + $output .= $right['width']; + $output .= '</span>'; + + $output .= '<span class="panels-flexible-splitter-right-scale">'; + $output .= isset($renderer->scale[$right_id]) ? $renderer->scale[$right_id] : 1; + $output .= '</span>'; + + $output .= '<span class="panels-flexible-splitter-right-width-type">'; + // If there is no right, make it fluid. + $output .= $right_id ? $right['width_type'] : '%'; + $output .= '</span>'; + + $output .= '</div>'; + return $output; +} + +/** + * Render the dropdown links for an item. + */ +function panels_flexible_render_item_links($renderer, $id, $item) { + $links = array(); + $remove = ''; + $add = ''; + if ($item['type'] == 'column') { + $title = t('Column'); + $settings = t('Column settings'); + if (empty($item['children'])) { + $remove = t('Remove column'); + $add = t('Add row'); + } + else { + $add = t('Add row to top'); + $add2 = t('Add row to bottom'); + } + } + else if ($item['type'] == 'row') { + if ($id == 'canvas') { + $title = t('Canvas'); + $settings = t('Canvas settings'); + } + else { + $title = t('Row'); + $settings = t('Row settings'); + } + if (empty($item['children'])) { + if ($id != 'canvas') { + $remove = t('Remove row'); + } + $add = $item['contains'] == 'region' ? t('Add region') : t('Add column'); + } + else { + $add = $item['contains'] == 'region' ? t('Add region to left') : t('Add column to left'); + $add2 = $item['contains'] == 'region' ? t('Add region to right') : t('Add column to right'); + } + } + else if ($item['type'] == 'region') { + $title = t('Region'); + $settings = t('Region settings'); + $remove = t('Remove region'); + } + + if (!empty($settings)) { + $links[] = array( + 'title' => $settings, + 'href' => $renderer->handler->get_url('layout', 'settings', $id), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + } + if ($add) { + $links[] = array( + 'title' => $add, + 'href' => $renderer->handler->get_url('layout', 'add', $id), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + } + if (isset($add2)) { + $links[] = array( + 'title' => $add2, + 'href' => $renderer->handler->get_url('layout', 'add', $id, 'right'), + 'attributes' => array('class' => 'ctools-use-modal'), + ); + } + if ($remove) { + $links[] = array( + 'title' => $remove, + 'href' => $renderer->handler->get_url('layout', 'remove', $id), + 'attributes' => array('class' => 'ctools-use-ajax'), + ); + } + + return theme('ctools_dropdown', $title, $links, FALSE, + 'flexible-layout-only flexible-links flexible-title flexible-links-' . $id); +} +/** + * Provide CSS for a flexible layout. + */ +function panels_flexible_render_css($renderer) { + if ($renderer->admin) { + $parent_class = '.' . $renderer->base['row'] . '-canvas'; + } + else { + $parent_class = '.' . $renderer->base['canvas']; + } + return panels_flexible_render_css_group($renderer, $renderer->settings['items']['canvas']['children'], $parent_class, 'column', 'canvas'); +} + +/** + * Render the CSS for a group of items to be displayed together. + * + * Columns and regions, when displayed as a group, need to cooperate in + * order to share margins and make sure that percent widths add up + * to the right total. + */ +function panels_flexible_render_css_group($renderer, $list, $owner_id, $type, $id) { + $css = array(); + + // Start off with some generic CSS to properly pad regions + $css['.' . $renderer->item_class['region']] = array( + 'padding' => '0', + ); + + $css['.' . $renderer->item_class['region'] . '-inside'] = array( + 'padding-right' => $renderer->region_separation, + 'padding-left' => $renderer->region_separation, + ); + + $css['.' . $renderer->item_class['region'] . '-inside-first'] = array( + 'padding-left' => '0', + ); + + $css['.' . $renderer->item_class['region'] . '-inside-last'] = array( + 'padding-right' => '0', + ); + + $css['.' . $renderer->item_class['column']] = array( + 'padding' => '0', + ); + + $css['.' . $renderer->item_class['column'] . '-inside'] = array( + 'padding-right' => $renderer->column_separation, + 'padding-left' => $renderer->column_separation, + ); + + $css['.' . $renderer->item_class['column'] . '-inside-first'] = array( + 'padding-left' => '0', + ); + + $css['.' . $renderer->item_class['column'] . '-inside-last'] = array( + 'padding-right' => '0', + ); + + // And properly pad rows too + $css['.' . $renderer->item_class['row']] = array( + 'padding' => '0 0 ' . $renderer->row_separation . ' 0', + 'margin' => '0', + ); + + $css['.' . $renderer->item_class['row'] . '-last'] = array( + 'padding-bottom' => '0', + ); + + panels_flexible_get_css_group($css, $renderer, $list, $owner_id, $type, $id); + + ctools_include('css'); + return ctools_css_assemble($css); +} + +/** + * Construct an array with all of the CSS properties for a group. + * + * This will parse down into children and produce all of the CSS needed if you + * start from the top. + */ +function panels_flexible_get_css_group(&$css, $renderer, $list, $owner_id, $type, $item_id) { + if ($type != 'row') { + // Go through our items and break up into right/center/right groups so we + // can figure out our offsets. + + // right == any items on the right that are 'fixed'. + // middle == all fluid items. + // right == any items on the right that are 'fixed'. + $left = $middle = $right = array(); + $left_total = $right_total = $middle_total = 0; + $current = 'left'; + foreach ($list as $id) { + if ($renderer->settings['items'][$id]['width_type'] == 'px') { + // fixed + if ($current == 'left') { + $left[] = $id; + $renderer->positions[$id] = 'left'; + $left_total += $renderer->settings['items'][$id]['width']; + } + else { + $current = 'right'; + $right[] = $id; + $renderer->positions[$id] = 'right'; + $right_total += $renderer->settings['items'][$id]['width']; + } + } + else { + // fluid + if ($current != 'right') { + $current = 'middle'; + $middle[] = $id; + $renderer->positions[$id] = 'middle'; + $middle_total += $renderer->settings['items'][$id]['width']; + } + // fall through: if current is 'right' and we ran into a 'fluid' then + // it gets *dropped* because that is invalid. + } + } + + // Go through our right sides and create CSS. + foreach ($left as $id) { + $class = "." . $renderer->base[$type] . "-$id"; + $css[$class] = array( + 'position' => 'relative', + 'float' => 'left', + 'background-color' => 'transparent', + 'width' => $renderer->settings['items'][$id]['width'] . "px", + ); + } + + // Do the same for right. + $right_pixels = 0; + + foreach ($right as $id) { + $class = "." . $renderer->base[$type] . "-$id"; + $css[$class] = array( + 'float' => 'left', + 'width' => $renderer->settings['items'][$id]['width'] . "px", + ); + } + + $max = count($middle) - 1; + + if ($middle_total) { + // Because we love IE so much, auto scale everything to 99%. This + // means adding up the actual widths and then providing a multiplier + // to each so that the total is 99%. + $scale = $renderer->scale_base / $middle_total; + foreach ($middle as $position => $id) { + $class = "." . $renderer->base[$type] . "-$id"; + $css[$class] = array( + 'float' => 'left', + 'width' => number_format($renderer->settings['items'][$id]['width'] * $scale, 4, '.', '') . "%", + ); + + // Store this so we can use it later. + // @todo: Store the scale, not the new width, so .js can adjust + // bi-directionally. + $renderer->scale[$id] = $scale; + } + } + + // If there is any total remaining, we need to offset the splitter + // by this much too. + if ($left_total) { + // Add this even if it's 0 so we can handle removals. + $css["$owner_id-inside"]['padding-left'] = '0px'; + if ($renderer->admin || count($middle)) { + $css["$owner_id-middle"]['margin-left'] = $left_total . 'px'; + // IE hack + $css["* html $owner_id-left"]['left'] = $left_total . "px"; + // Make this one very specific to the admin CSS so that preview + // does not stomp it. + $css[".panel-flexible-admin $owner_id-inside"]['padding-left'] = '0px'; + } + else { + $css["$owner_id-inside"]['margin-left'] = '-' . $left_total . 'px'; + $css["$owner_id-inside"]['padding-left'] = $left_total . 'px'; + // IE hack + $css["* html $owner_id-inside"]['left'] = $left_total . "px"; + } + } + if ($right_total) { + $css["$owner_id-middle"]['margin-right'] = $right_total . 'px'; + } + $css["$owner_id-inside"]['padding-right'] = '0px'; + } + + // If the canvas has a fixed width set, and this is the canvas, fix the + // width. + if ($item_id == 'canvas') { + $item = $renderer->settings['items'][$item_id]; + + if (!empty($item['fixed_width']) && intval($item['fixed_width'])) { + $css['.' . $renderer->base['canvas']]['width'] = intval($item['fixed_width']) . 'px'; + } + else { + $css['.' . $renderer->base['canvas']]['width'] = 'auto'; + } + } + + // Go through each item and process children. + foreach ($list as $id) { + $item = $renderer->settings['items'][$id]; + if (empty($item['children'])) { + continue; + } + + if ($type == 'column') { + // Columns can only contain rows. + $child_type = 'row'; + } + else { + $child_type = isset($item['contains']) ? $item['contains'] : 'region'; + } + + $class = "." . $renderer->base[$type] . "-$id"; + panels_flexible_get_css_group($css, $renderer, $item['children'], $class, $child_type, $id); + } +} + +/** + * AJAX responder to edit flexible settings for an item. + * + * $handler object + * The display renderer handler object. + */ +function panels_ajax_flexible_edit_settings($handler, $id) { + $settings = &$handler->display->layout_settings; + panels_flexible_convert_settings($settings, $handler->plugins['layout']); + + if (empty($settings['items'][$id])) { + ctools_modal_render(t('Error'), t('Invalid item id.')); + } + + $item = &$settings['items'][$id]; + $siblings = array(); + + if ($id != 'canvas') { + $siblings = $settings['items'][$item['parent']]['children']; + } + + + switch ($item['type']) { + case 'column': + $title = t('Configure column'); + break; + case 'row': + if ($id == 'canvas') { + $title = t('Configure canvas'); + } + else { + $title = t('Configure row'); + } + break; + case 'region': + $title = t('Configure region'); + break; + } + + $form_state = array( + 'display' => &$handler->display, + 'item' => &$item, + 'id' => $id, + 'siblings' => $siblings, + 'settings' => &$settings, + 'ajax' => TRUE, + 'title' => $title, + 'op' => 'edit', + ); + + $output = ctools_modal_form_wrapper('panels_flexible_config_item_form', $form_state); + if (empty($output)) { + // If the width type changed then other nearby items will have + // to have their widths adjusted. + panels_edit_cache_set($handler->cache); + + $css_id = isset($handler->display->css_id) ? $handler->display->css_id : ''; + $renderer = panels_flexible_create_renderer(TRUE, $css_id, array(), $settings, $handler->display, $handler->plugins['layout'], $handler); + + $output = array(); + // If the item is a region, replace the title. + $class = $renderer->base[$item['type']] . '-' . $id; + if ($item['type'] == 'region') { + $output[] = ctools_ajax_command_replace(".$class h2.label", + '<h2 class="label">' . check_plain($item['title']) . '</h2>'); + } + + // Rerender our links in case something changed. + $output[] = ctools_ajax_command_replace('.flexible-links-' . $id, + panels_flexible_render_item_links($renderer, $id, $item)); + + // If editing the canvas, reset the CSS width + if ($id == 'canvas') { + // update canvas CSS. + $css = array( + '.' . $renderer->item_class['column'] . '-inside' => array( + 'padding-left' => $renderer->column_separation, + 'padding-right' => $renderer->column_separation, + ), + '.' . $renderer->item_class['region'] . '-inside' => array( + 'padding-left' => $renderer->region_separation, + 'padding-right' => $renderer->region_separation, + ), + '.' . $renderer->item_class['row'] => array( + 'padding-bottom' => $renderer->row_separation, + ), + ); + if (!empty($item['fixed_width']) && intval($item['fixed_width'])) { + $css['.' . $renderer->base['canvas']] = array('width' => intval($item['fixed_width']) . 'px'); + } + else { + $css['.' . $renderer->base['canvas']] = array('width' => 'auto'); + } + foreach ($css as $selector => $data) { + $output[] = ctools_ajax_command_css($selector, $data); + } + } + + $output[] = ctools_modal_command_dismiss(); + } + + $handler->commands = $output; +} + +/** + * Configure a row, column or region on the flexible page. + * + * @param <type> $form_state + * @return <type> + */ +function panels_flexible_config_item_form(&$form_state) { + $display = &$form_state['display']; + $item = &$form_state['item']; + $siblings = &$form_state['siblings']; + $settings = &$form_state['settings']; + $id = &$form_state['id']; + + if ($item['type'] == 'region') { + $form['title'] = array( + '#title' => t('Region title'), + '#type' => 'textfield', + '#default_value' => $item['title'], + '#required' => TRUE, + ); + } + + if ($id == 'canvas') { + $form['class'] = array( + '#title' => t('Canvas class'), + '#type' => 'textfield', + '#default_value' => isset($item['class']) ? $item['class'] : '', + '#description' => t('This class will the primary class for this layout. It will also be appended to all column, row and region_classes to ensure that layouts within layouts will not inherit CSS from each other. If left blank, the name of the layout or ID of the display will be used.'), + ); + + $form['column_class'] = array( + '#title' => t('Column class'), + '#type' => 'textfield', + '#default_value' => isset($item['column_class']) ? $item['column_class'] : '', + '#description' => t('This class will be applied to all columns of the layout. If left blank this will be panels-flexible-column.'), + ); + + $form['row_class'] = array( + '#title' => t('Row class'), + '#type' => 'textfield', + '#default_value' => isset($item['row_class']) ? $item['row_class'] : '', + '#description' => t('This class will be applied to all rows of the layout. If left blank this will be panels-flexible-row.'), + ); + + $form['region_class'] = array( + '#title' => t('Region class'), + '#type' => 'textfield', + '#default_value' => isset($item['region_class']) ? $item['region_class'] : '', + '#description' => t('This class will be applied to all regions of the layout. If left blank this will be panels-flexible-region.'), + ); + + $form['no_scale'] = array( + '#type' => 'checkbox', + '#title' => t('Scale fluid widths for IE6'), + '#description' => t('IE6 does not do well with 100% widths. If checked, width will be scaled to 99% to compensate.'), + '#default_value' => empty($item['no_scale']), + ); + + $form['fixed_width'] = array( + '#type' => 'textfield', + '#title' => t('Fixed width'), + '#description' => t('If a value is entered, the layout canvas will be fixed to the given pixel width.'), + '#default_value' => isset($item['fixed_width']) ? $item['fixed_width'] : '', + ); + + $form['column_separation'] = array( + '#type' => 'textfield', + '#title' => t('Column separation'), + '#description' => t('How much padding to put on columns that are that are next to other columns. Note that this is put on both columns so the real amount is doubled.'), + '#default_value' => isset($item['column_separation']) ? $item['column_separation'] : '0.5em', + ); + + $form['region_separation'] = array( + '#type' => 'textfield', + '#title' => t('Region separation'), + '#description' => t('How much padding to put on regions that are that are next to other regions. Note that this is put on both regions so the real amount is doubled.'), + '#default_value' => isset($item['region_separation']) ? $item['region_separation'] : '0.5em', + ); + + $form['row_separation'] = array( + '#type' => 'textfield', + '#title' => t('Row separation'), + '#description' => t('How much padding to put on beneath rows to separate them from each other. Because this is placed only on the bottom, not hte top, this is NOT doubled like column/region separation.'), + '#default_value' => isset($item['row_separation']) ? $item['row_separation'] : '0.5em', + ); + } + else { + $form['class'] = array( + '#title' => t('CSS class'), + '#type' => 'textfield', + '#default_value' => isset($item['class']) ? $item['class'] : '', + '#description' => t('Enter a CSS class that will be used. This can be used to apply automatic styling from your theme, for example.'), + ); + + if ($item['type'] != 'row') { + // Test to see if there are fluid items to the left or the right. If there + // are fluid items on both sides, this item cannot be set to fixed. + $left = $right = FALSE; + $current = 'left'; + foreach ($siblings as $sibling) { + if ($sibling == $id) { + $current = 'right'; + } + else if ($settings['items'][$sibling]['width_type'] == '%') { + $$current = TRUE; // Indirection. + } + } + + $form['width_type'] = array( + '#type' => 'select', + '#title' => t('Width'), + '#default_value' => $item['width_type'], + '#options' => array( + '%' => t('Fluid'), + 'px' => t('Fixed'), + ), + '#disabled' => TRUE, + ); + } + else { + $form['contains'] = array( + '#type' => 'select', + '#title' => t('Contains'), + '#default_value' => $item['contains'], + '#options' => array( + 'region' => t('Regions'), + 'column' => t('Columns'), + ), + ); + + if (!empty($item['children'])) { + $form['contains']['#disabled'] = TRUE; + $form['contains']['#value'] = $item['contains']; + $form['contains']['#description'] = t('You must remove contained items to change the row container type.'); + } + } + } + + $form['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +/** + * Submit handler for editing a flexible item. + */ +function panels_flexible_config_item_form_submit(&$form, &$form_state) { + $item = &$form_state['item']; + if ($item['type'] == 'region') { + $item['title'] = $form_state['values']['title']; + } + + $item['class'] = $form_state['values']['class']; + + if ($form_state['id'] == 'canvas') { + $item['column_class'] = $form_state['values']['column_class']; + $item['row_class'] = $form_state['values']['row_class']; + $item['region_class'] = $form_state['values']['region_class']; + // Reverse this as the checkbox is backward from how we actually store + // it to make it simpler to default to scaling. + $item['no_scale'] = !$form_state['values']['no_scale']; + $item['fixed_width'] = $form_state['values']['fixed_width']; + $item['column_separation'] = $form_state['values']['column_separation']; + $item['region_separation'] = $form_state['values']['region_separation']; + $item['row_separation'] = $form_state['values']['row_separation']; + } + else if ($item['type'] != 'row') { + $item['width_type'] = $form_state['values']['width_type']; + } + else { + $item['contains'] = $form_state['values']['contains']; + } + +} + +/** + * AJAX responder to add a new row, column or region to a flexible layout. + */ +function panels_ajax_flexible_edit_add($handler, $id, $location = 'left') { + ctools_include('modal'); + ctools_include('ajax'); + $settings = &$handler->display->layout_settings; + panels_flexible_convert_settings($settings, $handler->plugins['layout']); + + if (empty($settings['items'][$id])) { + ctools_modal_render(t('Error'), t('Invalid item id.')); + } + + $parent = &$settings['items'][$id]; + + switch ($parent['type']) { + case 'column': + $title = t('Add row'); + // Create the new item with defaults. + $item = array( + 'type' => 'row', + 'contains' => 'region', + 'children' => array(), + 'parent' => $id, + ); + break; + case 'row': + switch ($parent['contains']) { + case 'region': + $title = $location == 'left' ? t('Add region to left') : t('Add region to right'); + $item = array( + 'type' => 'region', + 'title' => '', + 'width' => 100, + 'width_type' => '%', + 'parent' => $id, + ); + break; + case 'column': + $title = $location == 'left' ? t('Add column to left') : t('Add column to right'); + $item = array( + 'type' => 'column', + 'width' => 100, + 'width_type' => '%', + 'parent' => $id, + 'children' => array(), + ); + break; + } + // Create the new item with defaults. + break; + case 'region': + // Cannot add items to regions. + break; + } + + $form_state = array( + 'display' => &$handler->display, + 'parent' => &$parent, + 'item' => &$item, + 'id' => $id, + 'settings' => &$settings, + 'ajax' => TRUE, + 'title' => $title, + 'location' => $location, + ); + + $output = ctools_modal_form_wrapper('panels_flexible_add_item_form', $form_state); + if (empty($output)) { + // If the width type changed then other nearby items will have + // to have their widths adjusted. + panels_edit_cache_set($handler->cache); + $output = array(); + + $css_id = isset($handler->display->css_id) ? $handler->display->css_id : ''; + // Create a renderer object so we can render our new stuff. + $renderer = panels_flexible_create_renderer(TRUE, $css_id, array(), $settings, $handler->display, $handler->plugins['layout'], $handler); + + $content = ''; + if ($item['type'] == 'region') { + $handler->plugins['layout']['panels'][$form_state['key']] = $item['title']; + + $content = $handler->render_region($form_state['key'], array()); + + // Manually add the hidden field that our region uses to store pane info. + $content .= '<input type="hidden" name="panel[pane][' . + $form_state['key'] . ']" id="edit-panel-pane-' . $form_state['key'] . '" value="" />'; + + } + else { + // We need to make sure the left/middle/right divs exist inside this + // so that more stuff can be added inside it as needed. + foreach (array('left', 'middle', 'right') as $position) { + if (!empty($content) || $renderer->admin) { + $content .= '<div class="' . $renderer->base[$item['type']] . '-' . $form_state['key'] . '-' . $position . '"></div>'; + } + } + + } + + // render the item + $parent_class = $renderer->base[$parent['type']] . '-' . $id; + $item_output = panels_flexible_render_item($renderer, $item, $content, $form_state['key'], 0, 0, $item['type'] == 'row'); + + // Get all the CSS necessary for the entire row (as width adjustments may + // have cascaded). + $css = array(); + panels_flexible_get_css_group($css, $renderer, $parent['children'], '.' . $parent_class, $item['type'], $id); + + $position = isset($renderer->positions[$form_state['key']]) ? $renderer->positions[$form_state['key']] : 'middle'; + // If there's a nearby item, add the splitter and rewrite the width + // of the nearby item as it probably got adjusted. + // The blocks of code in this else look very similar but are not actually + // duplicated because the order changes based on left or right. + switch ($position) { + case 'left': + if ($location == 'left') { + $item_output .= panels_flexible_render_splitter($renderer, $form_state['key'], $form_state['sibling']); + $output[] = ctools_ajax_command_prepend('#panels-dnd-main .' . $parent_class . '-left', $item_output); + } + else if ($location == 'right') { + // If we are adding to the right side of the left box, there is + // a splitter that we have to remove; then we add our box normally, + // and then add a new splitter for just our guy. + $output[] = ctools_ajax_command_remove('panels-flexible-splitter-for-' . $renderer->base[$item['type']] . '-' . $form_state['key']); + $item_output = panels_flexible_render_splitter($renderer, $form_state['sibling'], $form_state['key']) . $item_output; + $item_output .= panels_flexible_render_splitter($renderer, $form_state['key'], NULL); + $output[] = ctools_ajax_command_append('#panels-dnd-main .' . $parent_class . '-left', $item_output); + } + break; + case 'right': + if (!empty($form_state['sibling'])) { + $item_output = panels_flexible_render_splitter($renderer, $form_state['sibling'], $form_state['key']) . $item_output; + } + $output[] = ctools_ajax_command_append('#panels-dnd-main .' . $parent_class . '-right', $item_output); + break; + case 'middle': + if ($location == 'left') { + if (!empty($form_state['sibling'])) { + $item_output .= panels_flexible_render_splitter($renderer, $form_state['key'], $form_state['sibling']); + } + $output[] = ctools_ajax_command_prepend('#panels-dnd-main .' . $parent_class . '-middle', $item_output); + } + else { + if (!empty($form_state['sibling'])) { + $item_output = panels_flexible_render_splitter($renderer, $form_state['sibling'], $form_state['key']) . $item_output; + } + $output[] = ctools_ajax_command_append('#panels-dnd-main .' . $parent_class . '-middle', $item_output); + } + break; + + } + + // Send our fix height command. + $output[] = array('command' => 'flexible_fix_height'); + + if (!empty($form_state['sibling'])) { + $sibling_width = '#panels-dnd-main .' . $renderer->base[$item['type']] . '-' . $form_state['sibling'] . '-width'; + $output[] = ctools_ajax_command_html($sibling_width, $settings['items'][$form_state['sibling']]['width']); + } + foreach ($css as $selector => $data) { + $output[] = ctools_ajax_command_css($selector, $data); + } + + // Rerender our parent item links: + $output[] = ctools_ajax_command_replace('.flexible-links-' . $id, + panels_flexible_render_item_links($renderer, $id, $parent)); + + $output[] = array( + 'command' => 'flexible_fix_firstlast', + 'selector' => '.' . $parent_class . '-inside', + 'base' => 'panels-flexible-' . $item['type'], + ); + + $output[] = ctools_modal_command_dismiss(); + } + + $handler->commands = $output; +} +/** + * Form to add a row, column or region to a flexible layout. + * @param <type> $form_state + * @return <type> + */ +function panels_flexible_add_item_form(&$form_state) { + $display = &$form_state['display']; + $item = &$form_state['item']; + $parent = &$form_state['parent']; + $settings = &$form_state['settings']; + $location = &$form_state['location']; + $id = &$form_state['id']; + + if ($item['type'] == 'region') { + $form['title'] = array( + '#title' => t('Region title'), + '#type' => 'textfield', + '#default_value' => $item['title'], + '#required' => TRUE, + ); + } + + $form['class'] = array( + '#title' => t('CSS Class'), + '#type' => 'textfield', + '#default_value' => isset($item['class']) ? $item['class'] : '', + '#description' => t('Enter a CSS class that will be used. This can be used to apply automatic styling from your theme, for example.'), + ); + + if ($item['type'] != 'row') { + // If there is a 'fixed' type on the side we're adding to, then this + // must also be fixed. Otherwise it can be either and should default to + // fluid. + $restrict = FALSE; + + if (!empty($parent['children'])) { + if ($location == 'left') { + $sibling = reset($parent['children']); + } + else { + $sibling = end($parent['children']); + } + if ($settings['items'][$sibling]['width_type'] == 'px') { + $restrict = TRUE; + $item['width_type'] = 'px'; + } + } + + $form['width_type'] = array( + '#type' => 'select', + '#title' => t('Width'), + '#default_value' => $item['width_type'], + '#options' => array( + '%' => t('Fluid'), + 'px' => t('Fixed'), + ), + '#disabled' => $restrict, + ); + if ($restrict) { + // This forces the value because disabled items don't always send + // their data back. + $form['width_type']['#value'] = $item['width_type']; + $form['width_type']['#description'] = t('Items cannot be set to fluid if there are fixed items already on that side.'); + } + } + else { + $form['contains'] = array( + '#type' => 'select', + '#title' => t('Contains'), + '#default_value' => $item['contains'], + '#options' => array( + 'region' => t('Regions'), + 'column' => t('Columns'), + ), + ); + } + + $form['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +/** + * Submit handler for editing a flexible item. + */ +function panels_flexible_add_item_form_submit(&$form, &$form_state) { + $item = &$form_state['item']; + $parent = &$form_state['parent']; + $location = &$form_state['location']; + $settings = &$form_state['settings']; + + $item['class'] = $form_state['values']['class']; + + if ($item['type'] == 'region') { + $item['title'] = $form_state['values']['title']; + } + + if ($item['type'] != 'row') { + $item['width_type'] = $form_state['values']['width_type']; + } + else { + $item['contains'] = $form_state['values']['contains']; + } + + if ($item['type'] == 'region') { + // derive the region key from the title + $key = preg_replace("/[^a-z0-9]/", '_', drupal_strtolower($item['title'])); + while (isset($settings['items'][$key])) { + $key .= '_'; + } + $form_state['key'] = $key; + } + else { + $form_state['key'] = $key = max(array_keys($settings['items'])) + 1; + } + + $form_state['sibling'] = NULL; + if ($item['type'] != 'row' && !empty($parent['children'])) { + // Figure out what the width should be and adjust our sibling if + // necessary. + if ($location == 'left') { + $form_state['sibling'] = reset($parent['children']); + } + else { + $form_state['sibling'] = end($parent['children']); + + } + + // If there is no sibling, or the sibling is of a different type, + // the default 100 will work for either fixed or fluid. + if ($form_state['sibling'] && $settings['items'][$form_state['sibling']]['width_type'] == $item['width_type']) { + // steal half of the sibling's space. + $width = $settings['items'][$form_state['sibling']]['width'] / 2; + $settings['items'][$form_state['sibling']]['width'] = $width; + $item['width'] = $width; + } + } + + // Place the item. + $settings['items'][$key] = $item; + if ($location == 'left') { + array_unshift($parent['children'], $key); + } + else { + $parent['children'][] = $key; + } +} + +/** + * AJAX responder to remove an existing row, column or region from a flexible + * layout. + */ +function panels_ajax_flexible_edit_remove($handler, $id) { + $settings = &$handler->display->layout_settings; + panels_flexible_convert_settings($settings, $handler->plugins['layout']); + + if (empty($settings['items'][$id])) { + ctools_ajax_render_error(t('Invalid item id.')); + } + + $item = &$settings['items'][$id]; + $css_id = isset($handler->display->css_id) ? $handler->display->css_id : ''; + // Create a renderer object so we can render our new stuff. + $renderer = panels_flexible_create_renderer(TRUE, $css_id, array(), $settings, $handler->display, $handler->plugins['layout'], $handler); + + + $siblings = &$settings['items'][$item['parent']]['children']; + $parent_class = '.' . $renderer->base[$settings['items'][$item['parent']]['type']] . '-' . $item['parent']; + + // Find the offset of our array. This will also be the key because + // this is a simple array. + $offset = array_search($id, $siblings); + + // Only bother with this stuff if our item is fluid, since fixed is + // as fixed does. + if ($item['type'] != 'row') { + if (isset($siblings[$offset + 1])) { + $next = $siblings[$offset + 1]; + } + if (isset($siblings[$offset - 1])) { + $prev = $siblings[$offset - 1]; + } + + if ($item['width_type'] == '%') { + // First, try next. + if (isset($next) && $settings['items'][$next]['width_type'] == '%') { + $settings['items'][$next]['width'] += $item['width']; + } + // If that failed, try the previous one. + else if (isset($prev) && $settings['items'][$prev]['width_type'] == '%') { + $settings['items'][$prev]['width'] += $item['width']; + } + } + // Not sure what happens if they both failed. Maybe nothing. + } + + // Remove the item. + array_splice($siblings, $offset, 1); + + unset($settings['items'][$id]); + + // Save our new state. + panels_edit_cache_set($handler->cache); + $class = $renderer->base[$item['type']] . '-' . $id; + $output = array(); + + $output[] = ctools_ajax_command_remove('#panels-dnd-main .' . $class); + + // Regenerate the CSS for siblings. + if (!empty($siblings)) { + // Get all the CSS necessary for the entire row (as width adjustments may + // have cascaded). + $css = array(); + panels_flexible_get_css_group($css, $renderer, $siblings, $parent_class, $item['type'], $item['parent']); + foreach ($css as $selector => $data) { + $output[] = ctools_ajax_command_css($selector, $data); + } + } + + // There are potentially two splitters linked to this item to be removed. + if (!empty($prev)) { + $output[] = ctools_ajax_command_remove('.flexible-splitter-for-' . $renderer->base[$item['type']] . '-' . $prev); + } + + // Try to remove the 'next' one even if there isn't a $next. + $output[] = ctools_ajax_command_remove('.flexible-splitter-for-' . $renderer->base[$item['type']] . '-' . $id); + + if (!empty($prev) && !empty($next)) { + // Add a new splitter that links $prev and $next: + $splitter = panels_flexible_render_splitter($renderer, $prev, $next); + $prev_class = '#panels-dnd-main .' . $renderer->base[$item['type']] . '-' . $prev; + $output[] = ctools_ajax_command_after($prev_class, $splitter); + // Send our fix height command. + $output[] = array('command' => 'flexible_fix_height'); + } + // Rerender our parent item links: + $output[] = ctools_ajax_command_replace('.flexible-links-' . $item['parent'], + panels_flexible_render_item_links($renderer, $item['parent'], $settings['items'][$item['parent']])); + + $output[] = array( + 'command' => 'flexible_fix_firstlast', + 'selector' => $parent_class . '-inside', + 'base' => 'panels-flexible-' . $item['type'], + ); + + $handler->commands = $output; +} + +/** + * AJAX responder to store resize information when the user adjusts the + * splitter. + */ +function panels_ajax_flexible_edit_resize($handler) { + ctools_include('ajax'); + $settings = &$handler->display->layout_settings; + panels_flexible_convert_settings($settings, $handler->plugins['layout']); + + $settings['items'][$_POST['left']]['width'] = $_POST['left_width']; + if (!empty($_POST['right']) && $_POST['right'] != $_POST['left']) { + $settings['items'][$_POST['right']]['width'] = $_POST['right_width']; + } + + // Save our new state. + panels_edit_cache_set($handler->cache); + + $handler->commands = array('ok'); +} + +/** + * AJAX form to bring up the "reuse" modal. + */ +function panels_ajax_flexible_edit_reuse($handler) { + $settings = &$handler->display->layout_settings; + panels_flexible_convert_settings($settings, $handler->plugins['layout']); + + $form_state = array( + 'display' => &$handler->display, + 'settings' => &$settings, + 'ajax' => TRUE, + 'title' => t('Save this layout for reuse'), + ); + + $output = ctools_modal_form_wrapper('panels_flexible_reuse_form', $form_state); + if (empty($output)) { + // Create the new layout. + ctools_include('export'); + $layout = ctools_export_crud_new('panels_layout'); + $layout->plugin = 'flexible'; + $layout->name = $form_state['values']['name']; + $layout->admin_title = $form_state['values']['admin_title']; + $layout->admin_description = $form_state['values']['admin_description']; + $layout->category = $form_state['values']['category']; + $layout->settings = $handler->display->layout_settings; + + // Save it. + ctools_export_crud_save('panels_layout', $layout); + + if (empty($form_state['values']['keep'])) { + // Set the actual layout_settings to now use the newly minted layout: + $handler->display->layout = 'flexible:' . $layout->name; + $handler->display->layout_settings = array(); + + // Save our new state. + panels_edit_cache_set($handler->cache); + } + + // Dismiss the modal. + $output[] = ctools_modal_command_dismiss(); + } + + $handler->commands = $output; +} + +function panels_flexible_reuse_form(&$form_state) { + $form['markup'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => t('If you save this layout for reuse it will appear in the list of reusable layouts at admin/build/panels/layouts, and you will need to go there to edit it. This layout will then become an option for all future panels you make.'), + ); + + $form['admin_title'] = array( + '#type' => 'textfield', + '#title' => t('Administrative title'), + '#description' => t('This will appear in the administrative interface to easily identify it.'), + ); + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Machine name'), + '#description' => t('The machine readable name of this layout. It must be unique, and it must contain only alphanumeric characters and underscores. Once created, you will not be able to change this value!'), + ); + + $form['category'] = array( + '#type' => 'textfield', + '#title' => t('Category'), + '#description' => t('What category this layout should appear in. If left blank the category will be "Miscellaneous".'), + ); + + $form['admin_description'] = array( + '#type' => 'textarea', + '#title' => t('Administrative description'), + '#description' => t('A description of what this layout is, does or is for, for administrative use.'), + ); + + $form['keep'] = array( + '#type' => 'checkbox', + '#title' => t('Keep current panel layout flexible'), + '#description' => t('If checked, this panel will continue to use a generic flexible layout and will not use the saved layout. Use this option if you wish to clone this layout.'), + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; +} + +function panels_flexible_reuse_form_validate(&$form, &$form_state) { + if (empty($form_state['values']['name'])) { + form_error($form['name'], t('You must choose a machine name.')); + } + + ctools_include('export'); + $test = ctools_export_crud_load('panels_layout', $form_state['values']['name']); + if ($test) { + form_error($form['name'], t('That name is used by another layout: @layout', array('@layout' => $test->admin_title))); + } + + // Ensure name fits the rules: + if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) { + form_error($form['name'], t('Name must be alphanumeric or underscores only.')); + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.png new file mode 100644 index 0000000000000000000000000000000000000000..14b4779a0b4f7d3516092e6790310aa559c96fe9 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/flexible.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/grippie-vertical.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/grippie-vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..7d5b7eaf5e10d4d56c78ca2802aa10eaf6944344 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/flexible/grippie-vertical.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.css new file mode 100644 index 0000000000000000000000000000000000000000..fe5edfb4bb761b1f76e3ccd1e2c24cb5813a2728 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.css @@ -0,0 +1,21 @@ + +.panel-1col { +/* overflow: hidden; */ +} + +.panel-2col .panel-col-first .inside { + margin: 0; +} + + +.panel-1col .panel-col { +} + +#panels-edit-display .panel-pane, +#panels-edit-display .helperclass { + margin: .5em; +} + +.panel-2col .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.inc new file mode 100644 index 0000000000000000000000000000000000000000..619950f9b780055cdb5a15e58976b06d7afb08bc --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.inc @@ -0,0 +1,14 @@ +<?php + +/** + * implementation of hook_panels_layouts() + */ +// Plugin definition +$plugin = array( + 'title' => t('Single column'), + 'category' => t('Columns: 1'), + 'icon' => 'onecol.png', + 'theme' => 'panels_onecol', + 'css' => 'onecol.css', + 'panels' => array('middle' => t('Middle column')), +); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.png new file mode 100644 index 0000000000000000000000000000000000000000..176ed69e7f59d6705471a00705b143131cdc03a4 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/onecol.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/panels-onecol.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/panels-onecol.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..ccfd0c2263810fdd11d48c56c9749d6b16b8304d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/onecol/panels-onecol.tpl.php @@ -0,0 +1,19 @@ +<?php +/** + * @file + * Template for a 3 column panel layout. + * + * This template provides a very simple "one column" panel display layout. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * $content['middle']: The only panel in the layout. + */ +?> +<div class="panel-display panel-1col clear-block" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <div class="panel-panel panel-col"> + <div><?php print $content['middle']; ?></div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/panels-threecol-25-50-25.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/panels-threecol-25-50-25.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..20f11e836fad34ddefa3f94821409981b3a6aa8c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/panels-threecol-25-50-25.tpl.php @@ -0,0 +1,29 @@ +<?php +/** + * @file + * Template for the 1 column panel layout. + * + * This template provides a three column 25%-50%-25% panel display layout. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * - $content['left']: Content in the left column. + * - $content['middle']: Content in the middle column. + * - $content['right']: Content in the right column. + */ +?> +<div class="panel-display panel-3col clear-block" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <div class="panel-panel panel-col-first"> + <div class="inside"><?php print $content['left']; ?></div> + </div> + + <div class="panel-panel panel-col"> + <div class="inside"><?php print $content['middle']; ?></div> + </div> + + <div class="panel-panel panel-col-last"> + <div class="inside"><?php print $content['right']; ?></div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.css new file mode 100644 index 0000000000000000000000000000000000000000..2bffe57d59d4c33978bec45d660c6a81ebab2d59 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.css @@ -0,0 +1,35 @@ + +.panel-3col { +/* overflow: hidden; */ +} + +.panel-3col .panel-col-first { + float: left; + width: 25%; +} + +.panel-3col .panel-col-first .inside { + margin: 0 .5em 1em 0; +} + +.panel-3col .panel-col { + float: left; + width: 50%; +} + +.panel-3col .panel-col .inside { + margin: 0 .5em 1em .5em; +} + +.panel-3col .panel-col-last { + float: left; + width: 25%; +} + +.panel-3col .panel-col-last .inside { + margin: 0 0 1em .5em; +} + +.panel-3col .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.inc new file mode 100644 index 0000000000000000000000000000000000000000..fdd911a54f56624d6c4e7d6e351a73b9cee3b8d7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.inc @@ -0,0 +1,20 @@ +<?php + +/** + * implementation of hook_panels_layouts + */ +// Plugin definition +$plugin = array( + 'title' => t('Three column 25/50/25'), + 'category' => t('Columns: 3'), + 'icon' => 'threecol_25_50_25.png', + 'theme' => 'panels_threecol_25_50_25', + 'theme arguments' => array('id', 'content'), + 'css' => 'threecol_25_50_25.css', + 'panels' => array( + 'left' => t('Left side'), + 'middle' => t('Middle column'), + 'right' => t('Right side') + ), +); + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.png new file mode 100644 index 0000000000000000000000000000000000000000..ad6832a7b0cc3329880cfb2ea54b474d83c10924 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25/threecol_25_50_25.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/panels-threecol-25-50-25-stacked.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/panels-threecol-25-50-25-stacked.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..ff1096ae32300caece6481c0b99b638131ce51a9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/panels-threecol-25-50-25-stacked.tpl.php @@ -0,0 +1,46 @@ +<?php +/** + * @file + * Template for a 3 column panel layout. + * + * This template provides a three column 25%-50%-25% panel display layout, with + * additional areas for the top and the bottom. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * - $content['top']: Content in the top row. + * - $content['left']: Content in the left column. + * - $content['middle']: Content in the middle column. + * - $content['right']: Content in the right column. + * - $content['bottom']: Content in the bottom row. + */ +?> +<div class="panel-display panel-3col-stacked clear-block" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <?php if ($content['top']): ?> + <div class="panel-panel panel-col-top"> + <div class="inside"><?php print $content['top']; ?></div> + </div> + <?php endif ?> + + <div class="center-wrapper"> + <div class="panel-panel panel-col-first"> + <div class="inside"><?php print $content['left']; ?></div> + </div> + + <div class="panel-panel panel-col"> + <div class="inside"><?php print $content['middle']; ?></div> + </div> + + <div class="panel-panel panel-col-last"> + <div class="inside"><?php print $content['right']; ?></div> + </div> + </div> + + <?php if ($content['bottom']): ?> + <div class="panel-panel panel-col-bottom"> + <div class="inside"><?php print $content['bottom']; ?></div> + </div> + <?php endif ?> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.css new file mode 100644 index 0000000000000000000000000000000000000000..1aa00dad5b63b1a691f60054aa1710e806d428ee --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.css @@ -0,0 +1,45 @@ + +.panel-3col-stacked { +/* overflow: hidden; */ +} + +.panel-3col-stacked .panel-col-top, +.panel-3col-stacked .panel-col-bottom { + width: 100%; + clear: both; +} + +.panel-3col-stacked .panel-col-top .inside { + margin-bottom: .5em; +} + +.panel-3col-stacked .panel-col-first { + float: left; + width: 25%; +} + +.panel-3col-stacked .panel-col .inside { + margin: 0 .5em 1em .5em; +} + +.panel-3col-stacked .panel-col { + float: left; + width: 50%; +} + +.panel-3col-stacked .panel-col .inside { + margin: 0 .5em 1em .5em; +} + +.panel-3col-stacked .panel-col-last { + float: left; + width: 25%; +} + +.panel-3col-stacked .panel-col-last .inside { + margin: 0 0 1em .5em; +} + +.panel-3col-stacked .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.inc new file mode 100644 index 0000000000000000000000000000000000000000..4d6158e378e53cec9315158bcebb0f3b24a062c7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.inc @@ -0,0 +1,17 @@ +<?php + +// Plugin definition +$plugin = array( + 'title' => t('Three column 25/50/25 stacked'), + 'category' => t('Columns: 3'), + 'icon' => 'threecol_25_50_25_stacked.png', + 'theme' => 'panels_threecol_25_50_25_stacked', + 'css' => 'threecol_25_50_25_stacked.css', + 'panels' => array( + 'top' => t('Top'), + 'left' => t('Left side'), + 'middle' => t('Middle column'), + 'right' => t('Right side'), + 'bottom' => t('Bottom'), + ), +); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.png new file mode 100644 index 0000000000000000000000000000000000000000..14b4779a0b4f7d3516092e6790310aa559c96fe9 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_25_50_25_stacked/threecol_25_50_25_stacked.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/panels-threecol-33-34-33.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/panels-threecol-33-34-33.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..0789982912842b794bc221436e67f8d619b44844 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/panels-threecol-33-34-33.tpl.php @@ -0,0 +1,31 @@ +<?php +/** + * @file + * Template for a 3 column panel layout. + * + * This template provides a three column panel display layout, with + * each column roughly equal in width. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * - $content['left']: Content in the left column. + * - $content['middle']: Content in the middle column. + * - $content['right']: Content in the right column. + */ +?> + +<div class="panel-display panel-3col-33 clear-block" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <div class="panel-panel panel-col-first"> + <div class="inside"><?php print $content['left']; ?></div> + </div> + + <div class="panel-panel panel-col"> + <div class="inside"><?php print $content['middle']; ?></div> + </div> + + <div class="panel-panel panel-col-last"> + <div class="inside"><?php print $content['right']; ?></div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.css new file mode 100644 index 0000000000000000000000000000000000000000..da2d93108331a2339025eff4a4169297d5517964 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.css @@ -0,0 +1,35 @@ + +.panel-3col-33 { +/* overflow: hidden; */ +} + +.panel-3col-33 .panel-col-first { + float: left; + width: 33%; +} + +.panel-3col-33 .panel-col-first .inside { + margin: 0 .5em 1em 0; +} + +.panel-3col-33 .panel-col { + float: left; + width: 33%; +} + +.panel-3col-33 .panel-col .inside { + margin: 0 .5em 1em .5em; +} + +.panel-3col-33 .panel-col-last { + float: left; + width: 33%; +} + +.panel-3col-33 .panel-col-last .inside { + margin: 0 0 1em .5em; +} + +.panel-3col-33 .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.inc new file mode 100644 index 0000000000000000000000000000000000000000..d770596e2e161e61e47fd7a0b1e1846497b2ac69 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.inc @@ -0,0 +1,15 @@ +<?php + +// Plugin definition +$plugin = array( + 'title' => t('Three column 33/34/33'), + 'category' => t('Columns: 3'), + 'icon' => 'threecol_33_34_33.png', + 'theme' => 'panels_threecol_33_34_33', + 'css' => 'threecol_33_34_33.css', + 'panels' => array( + 'left' => t('Left side'), + 'middle' => t('Middle column'), + 'right' => t('Right side') + ), +); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.png new file mode 100644 index 0000000000000000000000000000000000000000..468f8bbe84d91eaeebcce79226896c259157d362 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33/threecol_33_34_33.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/panels-threecol-33-34-33-stacked.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/panels-threecol-33-34-33-stacked.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..5c84a482ceec2bf9a8de46137d9d1ef28dc62f74 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/panels-threecol-33-34-33-stacked.tpl.php @@ -0,0 +1,46 @@ +<?php +/** + * @file + * Template for a 3 column panel layout. + * + * This template provides a three column 25%-50%-25% panel display layout, with + * additional areas for the top and the bottom. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * - $content['top']: Content in the top row. + * - $content['left']: Content in the left column. + * - $content['middle']: Content in the middle column. + * - $content['right']: Content in the right column. + * - $content['bottom']: Content in the bottom row. + */ +?> +<div class="panel-display panel-3col-33-stacked clear-block" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <?php if ($content['top']): ?> + <div class="panel-panel panel-col-top"> + <div class="inside"><?php print $content['top']; ?></div> + </div> + <?php endif ?> + + <div class="center-wrapper"> + <div class="panel-panel panel-col-first"> + <div class="inside"><?php print $content['left']; ?></div> + </div> + + <div class="panel-panel panel-col"> + <div class="inside"><?php print $content['middle']; ?></div> + </div> + + <div class="panel-panel panel-col-last"> + <div class="inside"><?php print $content['right']; ?></div> + </div> + </div> + + <?php if ($content['bottom']): ?> + <div class="panel-panel panel-col-bottom"> + <div class="inside"><?php print $content['bottom']; ?></div> + </div> + <?php endif ?> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.css new file mode 100644 index 0000000000000000000000000000000000000000..57b87ee3fdf6534d400af13de2c8ce7c5414965f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.css @@ -0,0 +1,45 @@ + +.panel-3col-33-stacked { +/* overflow: hidden; */ +} + +.panel-3col-33-stacked .panel-col-top, +.panel-3col-33-stacked .panel-col-bottom { + width: 100%; + clear: both; +} + +.panel-3col-33-stacked .panel-col-top .inside { + margin-bottom: 1em; +} + +.panel-3col-33-stacked .panel-col-first { + float: left; + width: 33%; +} + +.panel-3col-33-stacked .panel-col-first .inside { + margin: 0 .5em 1em 0; +} + +.panel-3col-33-stacked .panel-col { + float: left; + width: 33%; +} + +.panel-3col-33-stacked .panel-col .inside { + margin: 0 .5em 1em .5em; +} + +.panel-3col-33-stacked .panel-col-last { + float: left; + width: 33%; +} + +.panel-3col-33-stacked .panel-col-last .inside { + margin: 0 0 1em .5em; +} + +.panel-3col-33-stacked .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.inc new file mode 100644 index 0000000000000000000000000000000000000000..73a5a19e606930a3cf28d52d2507f1fa830e326c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.inc @@ -0,0 +1,17 @@ +<?php + +// Plugin definition +$plugin = array( + 'title' => t('Three column 33/34/33 stacked'), + 'category' => t('Columns: 3'), + 'icon' => 'threecol_33_34_33_stacked.png', + 'theme' => 'panels_threecol_33_34_33_stacked', + 'css' => 'threecol_33_34_33_stacked.css', + 'panels' => array( + 'top' => t('Top'), + 'left' => t('Left side'), + 'middle' => t('Middle column'), + 'right' => t('Right side'), + 'bottom' => t('Bottom') + ), +); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.png new file mode 100644 index 0000000000000000000000000000000000000000..ffd1351367c03371fbc00d7cde6a435ce0998df8 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/threecol_33_34_33_stacked/threecol_33_34_33_stacked.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/panels-twocol.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/panels-twocol.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..e72fcaf10c8d2bd0222f02f0e8c60a5571e2a572 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/panels-twocol.tpl.php @@ -0,0 +1,25 @@ +<?php +/** + * @file + * Template for a 2 column panel layout. + * + * This template provides a two column panel display layout, with + * each column roughly equal in width. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * - $content['left']: Content in the left column. + * - $content['right']: Content in the right column. + */ +?> +<div class="panel-display panel-2col clear-block" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <div class="panel-panel panel-col-first"> + <div class="inside"><?php print $content['left']; ?></div> + </div> + + <div class="panel-panel panel-col-last"> + <div class="inside"><?php print $content['right']; ?></div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.css new file mode 100644 index 0000000000000000000000000000000000000000..6e53ecaf1b3f0498a73e70df1d51116af2c68a28 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.css @@ -0,0 +1,37 @@ + +.panel-2col { +/* overflow: hidden; */ +} + +.panel-2col .panel-col-first { + float: left; + width: 50%; +} +* html .panel-2col .panel-col-first { + width: 49.9%; +} + +.panel-2col .panel-col-first .inside { + margin: 0 .5em 1em 0; +} + +.panel-2col .panel-col-last { + float: left; + width: 50%; +} +* html .panel-2col .panel-col-last { + width: 49.9%; +} + +.panel-2col .panel-col-last .inside { + margin: 0 0 1em .5em; +} + +#panels-edit-display .panel-pane, +#panels-edit-display .helperclass { + margin: .5em; +} + +.panel-2col .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.inc new file mode 100644 index 0000000000000000000000000000000000000000..315f996e9c63fad64b80e960ba01308560cb69fb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.inc @@ -0,0 +1,14 @@ +<?php + +// Plugin definition +$plugin = array( + 'title' => t('Two column'), + 'category' => t('Columns: 2'), + 'icon' => 'twocol.png', + 'theme' => 'panels_twocol', + 'css' => 'twocol.css', + 'panels' => array( + 'left' => t('Left side'), + 'right' => t('Right side') + ), +); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2965eb15b9750b40c5c7458cd5188c63f1ad59 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol/twocol.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/panels-twocol-bricks.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/panels-twocol-bricks.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..a447a0e5f4655e56bdaade99332195c9ba037aa7 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/panels-twocol-bricks.tpl.php @@ -0,0 +1,67 @@ +<?php +/** + * @file + * Template for a 2 column panel layout. + * + * This template provides a two column panel display layout, with + * each column roughly equal in width. It is 5 rows high; the top + * middle and bottom rows contain 1 column, while the second + * and fourth rows contain 2 columns. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * - $content['top']: Content in the top row. + * - $content['left_above']: Content in the left column in row 2. + * - $content['right_above']: Content in the right column in row 2. + * - $content['middle']: Content in the middle row. + * - $content['left_below']: Content in the left column in row 4. + * - $content['right_below']: Content in the right column in row 4. + * - $content['right']: Content in the right column. + * - $content['bottom']: Content in the bottom row. + */ +?> +<div class="panel-display panel-2col-bricks clear-block" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <?php if ($content['top']): ?> + <div class="panel-panel panel-col-top"> + <div class="inside"><?php print $content['top']; ?></div> + </div> + <?php endif ?> + + <?php if ($content['left_above'] || $content['right_above']): ?> + <div class="center-wrapper"> + <div class="panel-panel panel-col-first"> + <div class="inside"><?php print $content['left_above']; ?></div> + </div> + + <div class="panel-panel panel-col-last"> + <div class="inside"><?php print $content['right_above']; ?></div> + </div> + </div> + <?php endif ?> + + <?php if ($content['middle']): ?> + <div class="panel-panel panel-col-middle"> + <div class="inside"><?php print $content['middle']; ?></div> + </div> + <?php endif ?> + + <?php if ($content['left_below'] || $content['right_below']): ?> + <div class="center-wrapper"> + <div class="panel-panel panel-col-first"> + <div class="inside"><?php print $content['left_below']; ?></div> + </div> + + <div class="panel-panel panel-col-last"> + <div class="inside"><?php print $content['right_below']; ?></div> + </div> + </div> + <?php endif ?> + + <?php if ($content['bottom']): ?> + <div class="panel-panel panel-col-bottom"> + <div class="inside"><?php print $content['bottom']; ?></div> + </div> + <?php endif ?> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.css new file mode 100644 index 0000000000000000000000000000000000000000..4997ce600b71f2608509758bf881a4197fcd5d03 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.css @@ -0,0 +1,46 @@ + +.panel-2col-bricks { +/* overflow: hidden; */ + margin-top: 0; + padding-top: 0; +} + +.panel-2col-bricks .panel-col-top, +.panel-2col-bricks .panel-col-middle, +.panel-2col-bricks .panel-col-bottom { + width: 99.9%; + clear: both; +} + +.panel-2col-bricks .panel-col-top .inside, +.panel-2col-bricks .panel-col-middle .inside { + margin-bottom: .5em; +} + +.panel-2col-bricks .panel-col-first { + float: left; + width: 50%; +} +* html .panel-2col-bricks .panel-col-first { + width: 49.9%; +} + +.panel-2col-bricks .panel-col-first .inside { + margin: 0 .5em .5em 0; +} + +.panel-2col-bricks .panel-col-last { + float: left; + width: 50%; +} +* html .panel-2col-bricks .panel-col-last { + width: 49.9%; +} + +.panel-2col-bricks .panel-col-last .inside { + margin: 0 0 .5em .5em; +} + +.panel-2col-bricks .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.inc new file mode 100644 index 0000000000000000000000000000000000000000..0ade37fdf72a98595eeadb429b990f673109c90f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.inc @@ -0,0 +1,25 @@ +<?php + +/** + * @file + * Implementation for the two column bricked layout + */ + +// Plugin definition +$plugin = array( + 'title' => t('Two column bricks'), + 'category' => t('Columns: 2'), + 'icon' => 'twocol_bricks.png', + 'theme' => 'panels_twocol_bricks', + 'css' => 'twocol_bricks.css', + 'panels' => array( + 'top' => t('Top'), + 'left_above' => t('Left above'), + 'right_above' => t('Right above'), + 'middle' => t('Middle'), + 'left_below' => t('Left below'), + 'right_below' => t('Right below'), + 'bottom' => t('Bottom'), + ), +); + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.png new file mode 100644 index 0000000000000000000000000000000000000000..450395c801c960fdff5b5acb6100a314d7926042 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_bricks/twocol_bricks.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/panels-twocol-stacked.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/panels-twocol-stacked.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..a129725f883104f6ab192a4cc44c7b8b3b9744fb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/panels-twocol-stacked.tpl.php @@ -0,0 +1,40 @@ +<?php +/** + * @file + * Template for a 2 column panel layout. + * + * This template provides a two column panel display layout, with + * additional areas for the top and the bottom. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * - $content['top']: Content in the top row. + * - $content['left']: Content in the left column. + * - $content['right']: Content in the right column. + * - $content['bottom']: Content in the bottom row. + */ +?> +<div class="panel-2col-stacked clear-block panel-display" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>> + <?php if ($content['top']): ?> + <div class="panel-col-top panel-panel"> + <div class="inside"><?php print $content['top']; ?></div> + </div> + <?php endif; ?> + + <div class="center-wrapper"> + <div class="panel-col-first panel-panel"> + <div class="inside"><?php print $content['left']; ?></div> + </div> + <div class="panel-col-last panel-panel"> + <div class="inside"><?php print $content['right']; ?></div> + </div> + </div> + + <?php if ($content['bottom']): ?> + <div class="panel-col-bottom panel-panel"> + <div class="inside"><?php print $content['bottom']; ?></div> + </div> + <?php endif; ?> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.css new file mode 100644 index 0000000000000000000000000000000000000000..56eb3e346f351cc0dc88d24402faacfd370ff977 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.css @@ -0,0 +1,41 @@ + +.panel-2col-stacked { +/* overflow: hidden; */ + margin-top: 0; + padding-top: 0; +} + +.panel-2col-stacked .panel-col-top, +.panel-2col-stacked .panel-col-bottom { + width: 99.9%; + clear: both; +} + +.panel-2col-stacked .panel-col-top .inside { + margin-bottom: .5em; +} + +.panel-2col-stacked .panel-col-first { + float: left; + width: 50%; +} +* html .panel-2col-stacked .panel-col-first { + width: 49.9%; +} + +.panel-2col-stacked .panel-col-first .inside { + margin: 0 .5em 1em 0; +} + +.panel-2col-stacked .panel-col-last { + float: left; + width: 49.9%; +} + +.panel-2col-stacked .panel-col-last .inside { + margin: 0 0 1em .5em; +} + +.panel-2col-stacked .panel-separator { + margin: 0 0 1em 0; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.inc new file mode 100644 index 0000000000000000000000000000000000000000..aa59bffa61828d5d80c99a7612ebc46d0bd4b883 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.inc @@ -0,0 +1,16 @@ +<?php + +// Plugin definition +$plugin = array( + 'title' => t('Two column stacked'), + 'category' => t('Columns: 2'), + 'icon' => 'twocol_stacked.png', + 'theme' => 'panels_twocol_stacked', + 'css' => 'twocol_stacked.css', + 'panels' => array( + 'top' => t('Top'), + 'left' => t('Left side'), + 'right' => t('Right side'), + 'bottom' => t('Bottom') + ), +); diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.png new file mode 100644 index 0000000000000000000000000000000000000000..30ab8b67de949b6b2c2bc9140cef931119d94f5d Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/page_wizards/landing_page.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/page_wizards/landing_page.inc new file mode 100644 index 0000000000000000000000000000000000000000..e737a1d266ca040853c30cba66108de72cde8d93 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/page_wizards/landing_page.inc @@ -0,0 +1,271 @@ +<?php +/** + * @file + * A page creation wizard to quickly create simple landing pages. + * + * This wizard strips out a lot of features that are not normally needed for + * simple landing pages, such as access control, tabs, contexts, and the + * selection of a variant. It will just assume you want a panel and let you + * select the layout right away. This is 2 fewer forms than the standard + * add page process and it will point you at the finished page rather than + * sending you directly to the edit UI when finished. + * + * It also will auto-enable IPE if it can. + */ +$plugin = array( + 'title' => t('Landing page'), + 'page title' => t('Landing page wizard'), + 'description' => t('Landing pages are simple pages that have a path, possibly a visible menu entry, and a panel layout with simple content.'), + + 'type' => 'panels', + + 'form info' => array( + 'order' => array( + 'basic' => t('Basic settings'), + 'content' => t('Content'), + ), + + 'forms' => array( + 'basic' => array( + 'form id' => 'panels_landing_page_basic', + ), + 'content' => array( + 'form id' => 'panels_landing_page_content', + ), + ), + ), + + 'default cache' => 'panels_landing_page_new_page', + + 'finish' => 'panels_landing_page_finish', +); + +/** + * Provide defaults for a new cache. + * + * The cache will store all our temporary data; it isn't really a page + * in itself, but it does contain everything we need to make one at the end. + */ +function panels_landing_page_new_page(&$cache) { + $cache->name = ''; + $cache->admin_title = ''; + $cache->admin_description = ''; + $cache->path = ''; + $cache->menu_entry = FALSE; + $cache->menu = array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + 'name' => 'navigation', + 'parent' => array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + 'name' => 'navigation', + ), + ); + $cache->display = panels_new_display(); + $cache->display->layout = 'flexible'; +} + +/** + * First page of our page creator wizard. + */ +function panels_landing_page_basic(&$form, &$form_state) { + $cache = &$form_state['cache']; + ctools_include('dependent'); + + $form['admin_title'] = array( + '#type' => 'textfield', + '#title' => t('Administrative title'), + '#description' => t('The name of this page. This will appear in the administrative interface to easily identify it.'), + '#default_value' => $cache->admin_title, + '#required' => TRUE, + ); + + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Machine name'), + '#description' => t('The machine readable name of this page. It must be unique, and it must contain only alphanumeric characters and underscores. Once created, you will not be able to change this value!'), + '#default_value' => $cache->name, + '#required' => TRUE, + ); + + $form['admin_description'] = array( + '#type' => 'textarea', + '#title' => t('Administrative description'), + '#description' => t('A description of what this page is, does or is for, for administrative use.'), + '#default_value' => $cache->admin_description, + ); + + // path + $form['path'] = array( + '#type' => 'textfield', + '#title' => t('Path'), + '#default_value' => $cache->path, + '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='), + '#required' => TRUE, + ); + + $form['menu_entry'] = array( + '#type' => 'checkbox', + '#default_value' => $cache->menu_entry, + '#title' => t('Add a visible menu entry for this page'), + ); + + $form['menu']['#tree'] = TRUE; + + $form['menu']['title'] = array( + '#title' => t('Menu title'), + '#type' => 'textfield', + '#default_value' => $cache->menu['title'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-menu-entry' => array(1)), + ); + + // Only display the menu selector if menu module is enabled. + if (module_exists('menu')) { + $form['menu']['name'] = array( + '#title' => t('Menu'), + '#type' => 'select', + '#options' => menu_get_menus(), + '#default_value' => $cache->menu['name'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-menu-entry' => array(1)), + ); + } + else { + $form['menu']['name'] = array( + '#type' => 'value', + '#value' => $cache->menu['name'], + ); + $form['menu']['markup'] = array( + '#value' => t('Menu selection requires the activation of menu module.'), + ); + } + $form['menu']['weight'] = array( + '#title' => t('Weight'), + '#type' => 'textfield', + '#default_value' => isset($cache->menu['weight']) ? $cache->menu['weight'] : 0, + '#description' => t('The lower the weight the higher/further left it will appear.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-menu-entry' => array(1)), + ); + + ctools_include('page-wizard', 'panels'); + panels_page_wizard_add_layout($form, $form_state); +} + +/** + * Submit function to store the form data in our cache. + */ +function panels_landing_page_basic_validate(&$form, &$form_state) { + // Ensure all 'page' features are loaded. + $page_task = page_manager_get_task('page'); + + // Validate that the name is ok. + $test = page_manager_page_load($form_state['values']['name']); + if ($test) { + form_error($form['name'], t('That name is used by another page: @page', array('@page' => $test->admin_title))); + } + + // Ensure name fits the rules: + if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) { + form_error($form['name'], t('Page name must be alphanumeric or underscores only.')); + } + + // Validate that the path is ok. + if (preg_match('/[%!\?#&]/', $form_state['values']['path'])) { + form_error($form['path'], t('%, !, ?, #, or & cannot appear in the path.')); + } + + // Check to see if something is already using the path + $result = db_query("SELECT * FROM {menu_router} WHERE path = '%s'", $form_state['values']['path']); + while ($router = db_fetch_object($result)) { + form_error($form['path'], t('That path is already in use. This system cannot override existing paths.')); + return; + } + + // Ensure the path is not already an alias to something else. + $result = db_query("SELECT src, dst FROM {url_alias} WHERE dst = '%s'", $form_state['values']['path']); + if ($alias = db_fetch_object($result)) { + form_error($form['path'], t('That path is currently assigned to be an alias for @alias. This system cannot override existing aliases.', array('@alias' => $alias->src))); + } +} + +/** + * Submit function to store the form data in our cache. + */ +function panels_landing_page_basic_submit(&$form, &$form_state) { + $cache = &$form_state['cache']; + $cache->name = $form_state['values']['name']; + $cache->admin_title = $form_state['values']['admin_title']; + $cache->admin_description = $form_state['values']['admin_description']; + $cache->path = $form_state['values']['path']; + $cache->menu_entry = $form_state['values']['menu_entry']; + $cache->menu['title'] = $form_state['values']['menu']['title']; + $cache->menu['weight'] = $form_state['values']['menu']['weight']; + $cache->menu['name'] = $form_state['values']['menu']['name']; + $cache->menu['type'] = $cache->menu_entry ? 'normal' : 'none'; + $cache->display->layout = $form_state['values']['layout']; + $cache->display->title = $form_state['values']['admin_title']; +} + +/** + * Second page of our wizard. This one provides a layout and lets the + * user add content. + */ +function panels_landing_page_content(&$form, &$form_state) { + ctools_include('page-wizard', 'panels'); + panels_page_wizard_add_content($form, $form_state); +} + +/** + * Submit function to store the form data in our cache. + */ +function panels_landing_page_submit(&$form, &$form_state) { + panels_page_wizard_add_content_submit($form, $form_state); +} + +/** + * Finish callback for the wizard. + * + * When the wizard is finished, this callback will create the actual + * page, save it, and redirect the user to view the new work. + */ +function panels_landing_page_finish(&$form_state) { + $cache = &$form_state['cache']; + + // Ensure all 'page' features are loaded. + $page_task = page_manager_get_task('page'); + + // Assemble a new page subtask. + $subtask = page_manager_page_new(); + $subtask->name = $cache->name; + $subtask->path = $cache->path; + $subtask->admin_title = $cache->admin_title; + $subtask->admin_description = $cache->admin_description; + $subtask->path = $cache->path; + $subtask->menu = $cache->menu; + + // Create the the panel context variant configured with our display + $plugin = page_manager_get_task_handler('panel_context'); + + // Create a new handler. + $handler = page_manager_new_task_handler($plugin); + $handler->conf['title'] = t('Landing page'); + $handler->conf['display'] = $cache->display; + $handler->conf['pipeline'] = 'ipe'; + + // Assemble a new $page cache and assign it our page subtask and task + // handler. + $page = new stdClass(); + page_manager_page_new_page_cache($subtask, $page); + page_manager_handler_add_to_page($page, $handler); + + // Save it + page_manager_save_page_cache($page); + + // Send us to the new page immediately. + $form_state['redirect'] = url($cache->path); +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/page_wizards/node_override.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/page_wizards/node_override.inc new file mode 100644 index 0000000000000000000000000000000000000000..9f6ad5b2fbae3ca6b8d06aa7776357d45b0a7360 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/page_wizards/node_override.inc @@ -0,0 +1,289 @@ +<?php + +/** + * @file + * Page wizard that can create a variant on the node_view to take over a node + * for a particular type. + * + * This wizard does a lot that's cut and pasted from exports. We can get away + * with this because we know exports tend to remain relatively backward + * compatible, and because we know that our context IDs are locked in the + * node_view page. + */ +$plugin = array( + 'title' => t('Node template'), + 'page title' => t('Node template wizard'), + 'description' => t('The node page wizard can help you override the node page for a type of node.'), + + 'type' => 'panels', + + 'form info' => array( + 'order' => array( + 'type' => t('Select node type'), + 'content' => t('Content'), + ), + + 'forms' => array( + 'type' => array( + 'form id' => 'panels_node_override_basic', + ), + 'content' => array( + 'form id' => 'panels_node_override_content', + ), + ), + ), + + 'default cache' => 'panels_node_override_new_page', + + 'start' => 'panels_node_override_start', + 'finish' => 'panels_node_override_finish', +); + +/** + * Provide defaults for a new cache. + * + * The cache will store all our temporary data; it isn't really a page + * in itself, but it does contain everything we need to make one at the end. + */ +function panels_node_override_new_page(&$cache) { + $cache->type = ''; + $cache->display = panels_new_display(); + $cache->display->layout = 'flexible'; +} + +/** + * Callback called prior to the wizard starting up on every page + * load. + */ +function panels_node_override_start($form_info, $step, &$form_state) { + $form_state['page'] = page_manager_get_page_cache('node_view'); + if (!empty($form_state['page']->locked)) { + $account = user_load($form_state['page']->locked->uid); + $name = theme('username', $account); + $lock_age = format_interval(time() - $form_state['page']->locked->updated); + $break = url(page_manager_edit_url($form_state['page']->task_name, array('actions', 'break-lock'))); + + drupal_set_message(t('WARNING! The node_view is being edited by user !user, and is therefore locked from editing by others. This wizard cannot create a new node override while this page is locked. This lock is !age old. Click here to <a href="!break">break this lock</a>.', array('!user' => $name, '!age' => $lock_age, '!break' => $break)), 'warning'); + } +} + +/** + * First page of our page creator wizard. + */ +function panels_node_override_basic(&$form, &$form_state) { + $types = node_get_types(); + $form_state['types'] = $types; + + $already_done = array(); + // Figure out which types already have variants assigned to them. + foreach ($form_state['page']->handlers as $name => $handler) { + if ($handler->handler == 'panel_context' && !empty($handler->conf['access']['plugins'])) { + foreach ($handler->conf['access']['plugins'] as $plugin) { + if ($plugin['name'] == 'node_type') { + foreach ($plugin['settings']['type'] as $type) { + $already_done[$type] = $name; + } + } + } + } + } + + if ($already_done) { + $items = array(); + foreach ($already_done as $type => $handler_id) { + $items[] = check_plain($types[$type]->name) . ' ' . l(t('[Edit]'), page_manager_edit_url($form_state['page']->task_name, array('handlers', $handler_id, 'content'))); + } + + $form['already_done'] = array( + '#type' => 'item', + '#title' => t('Existing node templates'), + '#value' => theme('item_list', $items), + ); + } + + $options = array(); + foreach ($types as $name => $type) { + if (empty($already_done[$name])) { + $options[$name] = $type->name; + } + } + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Node type'), + '#options' => $options, + '#default_value' => $form_state['cache']->type, + ); + + ctools_include('page-wizard', 'panels'); + panels_page_wizard_add_layout($form, $form_state); +} + +/** + * Submit function to store the form data in our cache. + */ +function panels_node_override_basic_submit(&$form, &$form_state) { + $cache = &$form_state['cache']; + $cache->display->layout = $form_state['values']['layout']; + $cache->type = $form_state['values']['type']; + + // Create a new handler object and cache it; this way we can use the + // handler object for retrieving contexts properly. + // Create the the panel context variant configured with our display + $plugin = page_manager_get_task_handler('panel_context'); + + // Create a new handler. + $cache->handler = page_manager_new_task_handler($plugin); + $cache->handler->conf['title'] = $form_state['types'][$cache->type]->name; + $cache->handler->conf['pipeline'] = 'ipe'; + $cache->handler->conf['access'] = array( + 'plugins' => array( + 0 => array( + 'name' => 'node_type', + 'settings' => array( + 'type' => array( + $cache->type => $cache->type, + ), + ), + 'context' => 'argument_nid_1', + 'not' => FALSE, + ), + ), + 'logic' => 'and', + ); + + // Find a region by trying some basic main content region IDs. + $layout = panels_get_layout($form_state['values']['layout']); + $regions = panels_get_regions($layout, $cache->display); + foreach (array('center', 'middle', 'content', 'main') as $candidate) { + if (!empty($regions[$candidate])) { + $region = $candidate; + break; + } + } + + // If all of the above failed, use the first region. + if (empty($region)) { + $keys = array_keys($regions); + $region = reset($keys); + } + + // Populate the layout with content. This is from an export, with minor + // changes to ensure defaults are correct and to add stuff to the proper region. + $pane = new stdClass; + $pane->pid = 'new-1'; + $pane->panel = $region; + $pane->type = 'node_content'; + $pane->subtype = 'node_content'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'links' => 1, + 'page' => 1, + 'no_extras' => 0, + 'override_title' => 0, + 'override_title_text' => '', + 'identifier' => '', + 'link' => 0, + 'leave_node_title' => 0, + 'context' => 'argument_nid_1', + 'build_mode' => 'full', + ); + $pane->cache = array(); + $pane->style = array( + 'settings' => NULL, + ); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 0; + $cache->display->content['new-1'] = $pane; + $cache->display->panels[$region][0] = 'new-1'; + $pane = new stdClass; + $pane->pid = 'new-2'; + $pane->panel = $region; + $pane->type = 'node_comments'; + $pane->subtype = 'node_comments'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'mode' => variable_get('comment_default_mode', COMMENT_MODE_THREADED_EXPANDED), + 'order' => variable_get('comment_default_order', COMMENT_ORDER_NEWEST_FIRST), + 'comments_per_page' => variable_get('comment_default_per_page', '50'), + 'context' => 'argument_nid_1', + 'override_title' => 0, + 'override_title_text' => '', + ); + $pane->cache = array(); + $pane->style = array( + 'settings' => NULL, + ); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 1; + $cache->display->content['new-2'] = $pane; + $cache->display->panels[$region][1] = 'new-2'; + $pane = new stdClass; + $pane->pid = 'new-3'; + $pane->panel = $region; + $pane->type = 'node_comment_form'; + $pane->subtype = 'node_comment_form'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array( + 'anon_links' => 1, + 'context' => 'argument_nid_1', + 'override_title' => 0, + 'override_title_text' => '', + ); + $pane->cache = array(); + $pane->style = array( + 'settings' => NULL, + ); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 2; + $cache->display->content['new-3'] = $pane; + $cache->display->panels[$region][2] = 'new-3'; + + $task = page_manager_get_task('node_view'); + ctools_include('context'); + ctools_include('context-task-handler'); + $cache->context = ctools_context_handler_get_all_contexts($task, NULL, $cache->handler); + +} + +/** + * Second page of our wizard. This one provides a layout and lets the + * user add content. + */ +function panels_node_override_content(&$form, &$form_state) { + ctools_include('page-wizard', 'panels'); + panels_page_wizard_add_content($form, $form_state); +} + +/** + * Store changes to the display. + */ +function panels_node_override_content_submit(&$form, &$form_state) { + panels_page_wizard_add_content_submit($form, $form_state); +} + +/** + * Complete the wizard, create a new variant, and send them to the + * edit screen of that variant. + */ +function panels_node_override_finish(&$form_state) { + $page = &$form_state['page']; + $cache = &$form_state['cache']; + + // Add the new handler to the page + $cache->handler->conf['display'] = $cache->display; + page_manager_handler_add_to_page($page, $cache->handler); + + // Save it + page_manager_save_page_cache($page); + + // Send us to the page manager edit form for this. + $form_state['redirect'] = url(page_manager_edit_url('node_view', array('handlers', $cache->handler->name, 'content'))); + drupal_set_message(t('Your node template has been created.')); +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/icon.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..436355b84cbd1e4206df7f70f40d029f08eb5238 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/icon.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane-plain-box.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane-plain-box.css new file mode 100644 index 0000000000000000000000000000000000000000..5a01336664eb6d7813a7b630f29fc03db656e16c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane-plain-box.css @@ -0,0 +1,11 @@ +%style { + margin-bottom: 10px; + color: %text; + background-color: %background; +} + +%style h2 { + color: %header-text; + background-color: %header-background; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane-plain-box.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane-plain-box.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..73e3cc962c9a91220b98152c71f3ce3e0bb9326d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane-plain-box.tpl.php @@ -0,0 +1,16 @@ +<?php +/** + * @file + * + * Display the box for rounded corners. + * + * - $pane: The pane being rendered + * - $display: The display being rendered + * - $content: An object containing the content and title + * - $output: The result of theme('panels_pane') + * - $classes: The classes that must be applied to the top divs. + */ +?> +<div class="<?php print $classes ?>"> + <?php print $output; ?> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane_plain_box.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane_plain_box.inc new file mode 100644 index 0000000000000000000000000000000000000000..4adc4ad0f0d0c85036cd38cdfb2c7abc5261018f --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_plain_box/pane_plain_box.inc @@ -0,0 +1,93 @@ +<?php + +/** + * @file + * Definition of the style base for the rounded shadow box. + * + * This box is colorable, has rounded corners and a drop shadow. + */ + +$plugin = array( + 'category' => t('Basic styles'), + 'title' => t('Plain'), + 'description' => t('A plain box with an optional border. You may set the color of the text and the border.'), + 'module' => 'panels', + 'type' => 'pane', + + 'css' => 'pane-plain-box.css', + 'icon' => 'icon.png', + + 'defaults' => array('font' => array(), 'header_font' => array(), 'border' => array(), 'header_border' => array(), 'padding' => array()), + 'palette' => array( + 'background' => array( + 'label' => t('Background'), + 'default_value' => '#FFFFFF', + ), + 'text' => array( + 'label' => t('Text'), + 'default_value' => '#000000', + ), + 'border' => array( + 'label' => t('Border'), + 'default_value' => '#000000', + ), + 'header-background' => array( + 'label' => t('Header background'), + 'default_value' => '#FFFFFF', + ), + 'header-text' => array( + 'label' => t('Header text'), + 'default_value' => '#000000', + ), + 'header-border' => array( + 'label' => t('Header border'), + 'default_value' => '#000000', + ), + ), + + // This just uses theme_panels_pane because all we need is the class. +// 'theme' => 'pane_plain_box', +// 'preview' => 'panels_stylizer_pane_preview', + + 'settings form' => 'panels_pane_plain_box_style_settings', + 'settings form submit' => 'panels_pane_plain_box_style_settings_submit', + 'build' => 'panels_pane_plain_box_style_base_build', +); + +function panels_pane_plain_box_style_settings(&$form, &$form_state) { + $form['font'] = array(); + ctools_stylizer_font_selector_form($form['font'], $form_state, t('Font'), $form_state['settings']['font']); + + $form['border'] = array(); + ctools_stylizer_border_selector_form($form['border'], $form_state, t('Border'), $form_state['settings']['border']); + + $form['padding'] = array(); + ctools_stylizer_padding_selector_form($form['padding'], $form_state, t('Padding'), $form_state['settings']['padding']); + + $form['header_font'] = array(); + ctools_stylizer_font_selector_form($form['header_font'], $form_state, t('Header font'), $form_state['settings']['header_font']); + + $form['header_border'] = array(); + ctools_stylizer_border_selector_form($form['header_border'], $form_state, t('Header border'), $form_state['settings']['header_border']); + +} + +function panels_pane_plain_box_style_settings_submit(&$form, &$form_state) { + ctools_stylizer_font_selector_form_submit($form['font'], $form_state, $form_state['values']['font'], $form_state['settings']['font']); + ctools_stylizer_font_selector_form_submit($form['header_font'], $form_state, $form_state['values']['header_font'], $form_state['settings']['header_font']); + + ctools_stylizer_border_selector_form_submit($form['header_border'], $form_state, $form_state['values']['header_border'], $form_state['settings']['header_border']); + ctools_stylizer_border_selector_form_submit($form['border'], $form_state, $form_state['values']['border'], $form_state['settings']['border']); + + ctools_stylizer_padding_selector_form_submit($form['padding'], $form_state, $form_state['values']['padding'], $form_state['settings']['padding']); +} + +function panels_pane_plain_box_style_base_build($plugin, $settings, &$css, $replacements) { + ctools_stylizer_font_apply_style($css, '%style', $settings['font']); + ctools_stylizer_border_apply_style($css, '%style', $settings['border'], '%border'); + + ctools_stylizer_font_apply_style($css, '%style .pane-title', $settings['header_font']); + ctools_stylizer_border_apply_style($css, '%style .pane-title', $settings['header_border'], '%header-border', 'bottom'); + + ctools_stylizer_padding_apply_style($css, '%style .pane-title, %style .pane-content', $settings['padding']); +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/box-color.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/box-color.png new file mode 100644 index 0000000000000000000000000000000000000000..b67fd240cdddbf44d638136b10691d29e3ebf771 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/box-color.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/box-shadow.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/box-shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..01f385d6c92c49552d61013762c1221a7a0b8fad Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/box-shadow.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/icon.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c3a45729c0b817e77aa1cb9e843b99b98cfa0da3 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/icon.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane-rounded-shadow.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane-rounded-shadow.css new file mode 100644 index 0000000000000000000000000000000000000000..86eea4a6be1bbda7cfdf1c277281d2da16449689 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane-rounded-shadow.css @@ -0,0 +1,105 @@ +/* Show only to IE7 */ +*:first-child+html .rounded-shadow-background, +/* Show only to IE6 */ +* html .rounded-shadow-background { + margin: 0 -10px 0 0 !important; + padding: 10px 0 5px 0 !important; +} + +.rounded-shadow-top-edge, .rounded-shadow-bottom-edge, .rounded-shadow-left-edge, .rounded-shadow-right-edge, .rounded-shadow-wrap-corner { + position: relative; + /* hasLayout -1 ? For IE only */ + zoom: 1; +} +%style { + padding-top: 10px; + margin-bottom: 30px; + color: %text; +} + +%style h2 { + color: %header-text; +} + +%style .rounded-shadow-background { + margin: 10px; + background: %background url(rounded-shadow-background.png) repeat; +} + +%style .rounded-shadow-wrap-corner { + margin: -10px; +} + +%style .rounded-shadow-top-edge { + top: -10px; + background: url(rounded-shadow-top-edge.png) repeat-x 0 top; + font-size: 1px; +} + +%style .rounded-shadow-bottom-edge { + bottom: -10px; + background: url(rounded-shadow-bottom-edge.png) repeat-x 0 bottom; + font-size: 1px; +} + +%style .rounded-shadow-left-edge { + background: url(rounded-shadow-left-edge.png) repeat-y 0 0; +} + +%style .rounded-shadow-right-edge { + background: url(rounded-shadow-right-edge.png) repeat-y right 0; +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-top-edge, +%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge { + height: 19px; + margin: -10px 19px; +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-left, +%style .rounded-shadow-wrap-corner .rounded-shadow-right { + position: absolute; + top: 0; + height: 19px; + width: 19px; + margin: 0 -19px; +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-left { + background-image: url(rounded-shadow-top-left-corner.png); +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-right { + right: 0; + background-image: url(rounded-shadow-top-right-corner.png); +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge .rounded-shadow-left { + background-image: url(rounded-shadow-bottom-left-corner.png); +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge .rounded-shadow-right { + right: 0; + background-image: url(rounded-shadow-bottom-right-corner.png); +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-right-edge { + padding: 3px 19px; +} + +%style .panel-pane { + position: relative; top: -6px; +} + +/* +%style div.admin-links { + margin-top: -19px; + margin-left: -12px; +} + +%style .panel-separator { + background: url(rounded-shadow-bottom-edge.png) repeat-x 0 center; + font-size: 1px; + height: 30px; +} +*/ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane-rounded-shadow.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane-rounded-shadow.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..9edb6e0ce4ffe27f909f4d04241d597bca53d87e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane-rounded-shadow.tpl.php @@ -0,0 +1,31 @@ +<?php +/** + * @file + * + * Display the box for rounded corners. + * + * - $output: The content of the box. + * - $classes: The classes that must be applied to the top divs. + * - $pane: The pane being rendered + * - $display: The display being rendered + * - $content: The content being rendered (will be already in $output) + */ +?> +<div class="rounded-shadow <?php print $classes ?>"> + <div class="rounded-shadow-background"> + <div class="rounded-shadow-wrap-corner"> + <div class="rounded-shadow-top-edge"> + <div class="rounded-shadow-left"></div> + <div class="rounded-shadow-right"></div> + </div> + <div class="rounded-shadow-left-edge"> + <div class="rounded-shadow-right-edge clear-block"> + <?php print $output; ?> + </div> + </div> + <div class="rounded-shadow-bottom-edge"> + <div class="rounded-shadow-left"></div><div class="rounded-shadow-right"></div> + </div> + </div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane_rounded_shadow.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane_rounded_shadow.inc new file mode 100644 index 0000000000000000000000000000000000000000..d2bd3284e61297dbd15a611099de3294364469f1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/pane/pane_rounded_shadow/pane_rounded_shadow.inc @@ -0,0 +1,99 @@ +<?php + +/** + * @file + * Definition of the style base for the rounded shadow box. + * + * This box is colorable, has rounded corners and a drop shadow. + */ + +$plugin = array( + 'category' => t('Basic styles'), + 'title' => t('Rounded shadow box'), + 'module' => 'panels', + 'type' => 'pane', + 'css' => 'pane-rounded-shadow.css', + 'icon' => 'icon.png', + 'defaults' => array('header_font' => array(), 'text_font' => array(), 'padding' => array(), 'header_border' => array()), + 'palette' => array( + 'background' => array( + 'label' => t('Background'), + 'default_value' => '#FFFFFF', + ), + 'text' => array( + 'label' => t('Text'), + 'default_value' => '#000000', + ), + 'header-text' => array( + 'label' => t('Header text'), + 'default_value' => '#000000', + ), + 'header-border' => array( + 'label' => t('Header border'), + 'default_value' => '#000000', + ), + ), + 'actions' => array( + array('load', 'box', 'box-color.png'), + array('colorize', 'background'), + array('load', 'shadow', 'box-shadow.png'), + array('merge_from', 'box'), + array('slice', 'rounded-shadow-top-left-corner.png', 17, 49, 19, 19), + array('slice', 'rounded-shadow-top-right-corner.png', 473, 49, 19, 19), + array('slice', 'rounded-shadow-bottom-left-corner.png', 17, 442, 19, 19), + array('slice', 'rounded-shadow-bottom-right-corner.png', 473, 442, 19, 19), + array('slice', 'rounded-shadow-left-edge.png', 17, 60, 10, 10), + array('slice', 'rounded-shadow-right-edge.png', 474, 60, 18, 10), + array('slice', 'rounded-shadow-top-edge.png', 28, 49, 10, 10), + array('slice', 'rounded-shadow-bottom-edge.png', 28, 443, 10, 18), + array('slice', 'rounded-shadow-background.png', 150, 150, 1, 1), + ), + + 'theme' => 'pane_rounded_shadow', + 'build' => 'panels_rounded_shadow_style_base_build', +// 'preview' => 'panels_stylizer_pane_preview', + + 'settings form' => 'panels_pane_rounded_shadow_style_settings', + 'settings form submit' => 'panels_pane_rounded_shadow_style_settings_submit', + 'build' => 'panels_pane_rounded_shadow_style_base_build', +); + +function template_preprocess_pane_rounded_shadow(&$vars) { + $vars['classes'] = $vars['content']->css_class; + $vars['content']->css_class = ''; + + $vars['output'] = theme('panels_pane', $vars['content'], $vars['pane'], $vars['display']); +} + +function panels_pane_rounded_shadow_style_settings(&$form, &$form_state) { + $form['header_font'] = array(); + ctools_stylizer_font_selector_form($form['header_font'], $form_state, t('Header font'), $form_state['settings']['header_font']); + + $form['header_border'] = array(); + ctools_stylizer_border_selector_form($form['header_border'], $form_state, t('Header border'), $form_state['settings']['header_border']); + + $form['text_font'] = array(); + ctools_stylizer_font_selector_form($form['text_font'], $form_state, t('Text font'), $form_state['settings']['text_font']); + + $form['padding'] = array(); + ctools_stylizer_padding_selector_form($form['padding'], $form_state, t('Padding'), $form_state['settings']['padding']); +} + +function panels_pane_rounded_shadow_style_settings_submit(&$form, &$form_state) { + ctools_stylizer_font_selector_form_submit($form['header_font'], $form_state, $form_state['values']['header_font'], $form_state['settings']['header_font']); + + ctools_stylizer_font_selector_form_submit($form['text_font'], $form_state, $form_state['values']['text_font'], $form_state['settings']['text_font']); + + ctools_stylizer_padding_selector_form_submit($form['padding'], $form_state, $form_state['values']['padding'], $form_state['settings']['padding']); + + ctools_stylizer_border_selector_form_submit($form['header_border'], $form_state, $form_state['values']['header_border'], $form_state['settings']['header_border']); + +} + +function panels_pane_rounded_shadow_style_base_build($plugin, $settings, &$css, $replacements) { + ctools_stylizer_font_apply_style($css, '%style .pane-title', $settings['header_font']); + ctools_stylizer_border_apply_style($css, '%style .pane-title', $settings['header_border'], '%header-border', 'bottom'); + ctools_stylizer_font_apply_style($css, '%style .pane-content', $settings['text_font']); + ctools_stylizer_padding_apply_style($css, '%style', $settings['padding']); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/icon.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..436355b84cbd1e4206df7f70f40d029f08eb5238 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/icon.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region-plain-box.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region-plain-box.css new file mode 100644 index 0000000000000000000000000000000000000000..e48b6d5f8a86084015968cb96b0f13a26c6cf137 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region-plain-box.css @@ -0,0 +1,6 @@ +%style { + padding-top: 10px; + margin-bottom: 10px; + color: %text; + background-color: %background; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region-plain-box.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region-plain-box.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..837cb2cdc47d17d4435d20a12546d04fe23fc9f1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region-plain-box.tpl.php @@ -0,0 +1,28 @@ +<?php +/** + * @file + * + * Display the box for rounded corners. + * + * - $content: The content of the box. + * - $classes: The classes that must be applied to the top divs. + */ +?> +<div class="rounded-shadow <?php print $classes ?>"> + <div class="rounded-shadow-background"> + <div class="rounded-shadow-wrap-corner"> + <div class="rounded-shadow-top-edge"> + <div class="rounded-shadow-left"></div> + <div class="rounded-shadow-right"></div> + </div> + <div class="rounded-shadow-left-edge"> + <div class="rounded-shadow-right-edge clear-block"> + <?php print $content; ?> + </div> + </div> + <div class="rounded-shadow-bottom-edge"> + <div class="rounded-shadow-left"></div><div class="rounded-shadow-right"></div> + </div> + </div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region_plain_box.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region_plain_box.inc new file mode 100644 index 0000000000000000000000000000000000000000..daaf7c8b3d2100b6fc6fa91b2e2dbd1b864fb4b8 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_plain_box/region_plain_box.inc @@ -0,0 +1,65 @@ +<?php + +/** + * @file + * Definition of the style base for the rounded shadow box. + * + * This box is colorable, has rounded corners and a drop shadow. + */ + +$plugin = array( + 'category' => t('Basic styles'), + 'title' => t('Plain'), + 'description' => t('A plain box with an optional border. You may set the color of the text and the border.'), + 'module' => 'panels', + 'type' => 'region', + + 'css' => 'region-plain-box.css', + 'icon' => 'icon.png', + + 'defaults' => array('font' => array(), 'border' => array(), 'padding' => array()), + 'palette' => array( + 'background' => array( + 'label' => t('Background'), + 'default_value' => '#FFFFFF', + ), + 'text' => array( + 'label' => t('Text'), + 'default_value' => '#000000', + ), + 'border' => array( + 'label' => t('Border'), + 'default_value' => '#000000', + ), + ), + + 'theme' => 'region_plain_box', +// 'preview' => 'panels_stylizer_region_preview', + + 'settings form' => 'panels_region_plain_box_style_settings', + 'settings form submit' => 'panels_region_plain_box_style_settings_submit', + 'build' => 'panels_region_plain_box_style_base_build', +); + +function panels_region_plain_box_style_settings(&$form, &$form_state) { + $form['font'] = array(); + ctools_stylizer_font_selector_form($form['font'], $form_state, t('Font'), $form_state['settings']['font']); + + $form['border'] = array(); + ctools_stylizer_border_selector_form($form['border'], $form_state, t('Border'), $form_state['settings']['border']); + + $form['padding'] = array(); + ctools_stylizer_padding_selector_form($form['padding'], $form_state, t('Padding'), $form_state['settings']['padding']); +} + +function panels_region_plain_box_style_settings_submit(&$form, &$form_state) { + ctools_stylizer_font_selector_form_submit($form['font'], $form_state, $form_state['values']['font'], $form_state['settings']['font']); + ctools_stylizer_border_selector_form_submit($form['border'], $form_state, $form_state['values']['border'], $form_state['settings']['border']); + ctools_stylizer_padding_selector_form_submit($form['padding'], $form_state, $form_state['values']['padding'], $form_state['settings']['padding']); +} + +function panels_region_plain_box_style_base_build($plugin, $settings, &$css, $replacements) { + ctools_stylizer_font_apply_style($css, '%style', $settings['font']); + ctools_stylizer_border_apply_style($css, '%style', $settings['border'], '%border'); + ctools_stylizer_padding_apply_style($css, '%style', $settings['padding']); +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/box-color.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/box-color.png new file mode 100644 index 0000000000000000000000000000000000000000..b67fd240cdddbf44d638136b10691d29e3ebf771 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/box-color.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/box-shadow.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/box-shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..01f385d6c92c49552d61013762c1221a7a0b8fad Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/box-shadow.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/icon.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c3a45729c0b817e77aa1cb9e843b99b98cfa0da3 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/icon.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region-rounded-shadow.css b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region-rounded-shadow.css new file mode 100644 index 0000000000000000000000000000000000000000..924a6bf290696f57cf99e148248297f45457010d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region-rounded-shadow.css @@ -0,0 +1,97 @@ +/* Show only to IE7 */ +*:first-child+html .rounded-shadow-background, +/* Show only to IE6 */ +* html .rounded-shadow-background { + margin: 0 -10px 0 0 !important; + padding: 10px 0 5px 0 !important; +} + +.rounded-shadow-top-edge, .rounded-shadow-bottom-edge, .rounded-shadow-left-edge, .rounded-shadow-right-edge, .rounded-shadow-wrap-corner { + position: relative; + /* hasLayout -1 ? For IE only */ + zoom: 1; +} +%style { + padding-top: 10px; + margin-bottom: 30px; + color: %text; +} + +%style .rounded-shadow-background { + margin: 10px; + background: %background url(rounded-shadow-background.png) repeat; +} + +%style .rounded-shadow-wrap-corner { + margin: -10px; +} + +%style .rounded-shadow-top-edge { + top: -10px; + background: url(rounded-shadow-top-edge.png) repeat-x 0 top; + font-size: 1px; +} + +%style .rounded-shadow-bottom-edge { + bottom: -10px; + background: url(rounded-shadow-bottom-edge.png) repeat-x 0 bottom; + font-size: 1px; +} + +%style .rounded-shadow-left-edge { + background: url(rounded-shadow-left-edge.png) repeat-y 0 0; +} + +%style .rounded-shadow-right-edge { + background: url(rounded-shadow-right-edge.png) repeat-y right 0; +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-top-edge, +%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge { + height: 19px; + margin: -10px 19px; +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-left, +%style .rounded-shadow-wrap-corner .rounded-shadow-right { + position: absolute; + top: 0; + height: 19px; + width: 19px; + margin: 0 -19px; +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-left { + background-image: url(rounded-shadow-top-left-corner.png); +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-right { + right: 0; + background-image: url(rounded-shadow-top-right-corner.png); +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge .rounded-shadow-left { + background-image: url(rounded-shadow-bottom-left-corner.png); +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge .rounded-shadow-right { + right: 0; + background-image: url(rounded-shadow-bottom-right-corner.png); +} + +%style .rounded-shadow-wrap-corner .rounded-shadow-right-edge { + padding: 3px 19px; +} + +/* +%style div.admin-links { + margin-top: -19px; + margin-left: -12px; +} + +%style .panel-separator { + background: url(rounded-shadow-bottom-edge.png) repeat-x 0 center; + font-size: 1px; + height: 30px; +} +*/ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region-rounded-shadow.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region-rounded-shadow.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..837cb2cdc47d17d4435d20a12546d04fe23fc9f1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region-rounded-shadow.tpl.php @@ -0,0 +1,28 @@ +<?php +/** + * @file + * + * Display the box for rounded corners. + * + * - $content: The content of the box. + * - $classes: The classes that must be applied to the top divs. + */ +?> +<div class="rounded-shadow <?php print $classes ?>"> + <div class="rounded-shadow-background"> + <div class="rounded-shadow-wrap-corner"> + <div class="rounded-shadow-top-edge"> + <div class="rounded-shadow-left"></div> + <div class="rounded-shadow-right"></div> + </div> + <div class="rounded-shadow-left-edge"> + <div class="rounded-shadow-right-edge clear-block"> + <?php print $content; ?> + </div> + </div> + <div class="rounded-shadow-bottom-edge"> + <div class="rounded-shadow-left"></div><div class="rounded-shadow-right"></div> + </div> + </div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region_rounded_shadow.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region_rounded_shadow.inc new file mode 100644 index 0000000000000000000000000000000000000000..b73da907cab89c047546553f0779c19da4b93225 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/style_bases/region/region_rounded_shadow/region_rounded_shadow.inc @@ -0,0 +1,71 @@ +<?php + +/** + * @file + * Definition of the style base for the rounded shadow box. + * + * This box is colorable, has rounded corners and a drop shadow. + */ + +$plugin = array( + 'category' => t('Basic styles'), + 'title' => t('Rounded shadow box'), + 'module' => 'panels', + 'type' => 'region', + 'css' => 'region-rounded-shadow.css', + 'icon' => 'icon.png', + 'defaults' => array('font' => array(), 'padding' => array()), + 'palette' => array( + 'background' => array( + 'label' => t('Background'), + 'default_value' => '#FFFFFF', + ), + 'text' => array( + 'label' => t('Text color'), + 'default_value' => '#000000', + ), + ), + 'actions' => array( + array('load', 'box', 'box-color.png'), + array('colorize', 'background'), + array('load', 'shadow', 'box-shadow.png'), + array('merge_from', 'box'), + array('slice', 'rounded-shadow-top-left-corner.png', 17, 49, 19, 19), + array('slice', 'rounded-shadow-top-right-corner.png', 473, 49, 19, 19), + array('slice', 'rounded-shadow-bottom-left-corner.png', 17, 442, 19, 19), + array('slice', 'rounded-shadow-bottom-right-corner.png', 473, 442, 19, 19), + array('slice', 'rounded-shadow-left-edge.png', 17, 60, 10, 10), + array('slice', 'rounded-shadow-right-edge.png', 474, 60, 18, 10), + array('slice', 'rounded-shadow-top-edge.png', 28, 49, 10, 10), + array('slice', 'rounded-shadow-bottom-edge.png', 28, 443, 10, 18), + array('slice', 'rounded-shadow-background.png', 150, 150, 1, 1), + ), + + 'theme' => 'region_rounded_shadow', + + 'build' => 'panels_rounded_shadow_style_base_build', +// 'preview' => 'panels_stylizer_region_preview', + + 'settings form' => 'panels_region_rounded_shadow_style_settings', + 'settings form submit' => 'panels_region_rounded_shadow_style_settings_submit', + 'build' => 'panels_region_rounded_shadow_style_base_build', +); + +function panels_region_rounded_shadow_style_settings(&$form, &$form_state) { + $form['font'] = array(); + ctools_stylizer_font_selector_form($form['font'], $form_state, t('Font'), $form_state['settings']['font']); + + $form['padding'] = array(); + ctools_stylizer_padding_selector_form($form['padding'], $form_state, t('Padding'), $form_state['settings']['padding']); +} + +function panels_region_rounded_shadow_style_settings_submit(&$form, &$form_state) { + ctools_stylizer_font_selector_form_submit($form['font'], $form_state, $form_state['values']['font'], $form_state['settings']['font']); + ctools_stylizer_padding_selector_form_submit($form['padding'], $form_state, $form_state['values']['padding'], $form_state['settings']['padding']); +} + +function panels_region_rounded_shadow_style_base_build($plugin, $settings, &$css, $replacements) { + ctools_stylizer_font_apply_style($css, '%style', $settings['font']); + ctools_stylizer_padding_apply_style($css, '%style', $settings['padding']); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/block.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/block.inc new file mode 100644 index 0000000000000000000000000000000000000000..ab893625afdc6e09cedb9256fee19fe930c14d0c --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/block.inc @@ -0,0 +1,43 @@ +<?php + +/** + * @file + * Definition of the 'block' panel style. + */ + +// Plugin definition +$plugin = array( + 'title' => t('System block'), + 'description' => t('Display the pane as a system block; this is more restrictive than the default.'), + 'render pane' => 'panels_block_style_render_pane', + 'weight' => -10, +); + +/** + * Render callback. + * + * @ingroup themeable + */ +function theme_panels_block_style_render_pane($content, $pane, $display) { + if (empty($content->content)) { + return; + } + + if (!empty($content->title)) { + $content->subject = $content->title; + } + + $content->region = $pane->panel; + if (!isset($content->module)) { + $content->module = $content->type; + } + if (!isset($content->delta)) { + $content->delta = $content->subtype; + } + + // If using per pane classes, $block->css_class will need to be added in your + // preprocess or template, along with any other Panels specific field you + // might want to utilize. + return theme('block', $content); +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/corner-bits.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/corner-bits.png new file mode 100644 index 0000000000000000000000000000000000000000..73480e64795a9737c30ffd6dc17c57b9e8a59dad Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/corner-bits.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/panels-rounded-corners-box.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/panels-rounded-corners-box.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..ae8fb87a6a0463b5b3385432dfe8bcbb945fe9a9 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/panels-rounded-corners-box.tpl.php @@ -0,0 +1,20 @@ +<?php +/** + * @file + * + * Display the box for rounded corners. + * + * - $content: The content of the box. + */ +?> +<div class="rounded-corner"> + <div class="wrap-corner"> + <div class="t-edge"><div class="l"></div><div class="r"></div></div> + <div class="l-edge"> + <div class="r-edge clear-block"> + <?php print $content; ?> + </div> + </div> + <div class="b-edge"><div class="l"></div><div class="r"></div></div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/rounded_corners.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/rounded_corners.inc new file mode 100644 index 0000000000000000000000000000000000000000..6e20cdb3975a00ad541c821e78869317d0e6d9cb --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/rounded_corners.inc @@ -0,0 +1,198 @@ +<?php + +/** + * @file + * Definition of the 'rounded_corners' panel style. + */ + +// Plugin definition +$plugin = array( + 'title' => t('Rounded corners'), + 'description' => t('Presents the panes or panel regions with a rounded corner box around them'), + 'render region' => 'panels_rounded_corners_style_render_region', + 'render pane' => 'panels_rounded_corners_style_render_pane', + 'settings form' => 'panels_rounded_corners_style_settings_form', + 'hook theme' => array( + 'panels_rounded_corners_box' => array( + 'arguments' => array('content' => NULL), + 'path' => panels_get_path('plugins/styles/corners'), + 'template' => 'panels-rounded-corners-box', + ), + ), +); + +/** + * Render callback. + * + * @ingroup themeable + */ +function theme_panels_rounded_corners_style_render_region($display, $region_id, $panes, $settings) { + $output = ''; + + // Determine where to put the box. If empty or 'pane' around each pane. If + // 'panel' then just around the whole panel. + $where = empty($settings['corner_location']) ? 'pane' : $settings['corner_location']; + + $print_separator = FALSE; + foreach ($panes as $pane_id => $pane_output) { + if ($pane_output) { + // Add the separator if we've already displayed a pane. + if ($print_separator) { + $output .= '<div class="panel-region-separator"> </div>'; + } + + if ($where == 'pane') { + $output .= theme('panels_rounded_corners_box', $pane_output); + } + else { + $output .= $pane_output; + $print_separator = TRUE; + } + } + } + + if ($where == 'panel') { + $output = theme('panels_rounded_corners_box', $output); + } + + panels_add_rounded_corners_css($display, $where); + + return $output; +} + +function panels_add_rounded_corners_css($display, $where) { + static $displays_used = array(); + if (empty($displays_used[$display->css_id])) { + panels_rounded_corners_css($display, $where); + $displays_used[$display->css_id] = TRUE; + } +} + +/** + * Render callback for a single pane. + */ +function theme_panels_rounded_corners_style_render_pane($content, $pane, $display) { + if (empty($content->content)) { + return; + } + + $output = theme('panels_pane', $content, $pane, $display); + + // Just stick a box around the standard theme_panels_pane. + $output = theme('panels_rounded_corners_box', $output); + panels_add_rounded_corners_css($display, 'pane'); + return $output; +} + +/** + * Settings form callback. + */ +function panels_rounded_corners_style_settings_form($style_settings) { + $form['corner_location'] = array( + '#type' => 'select', + '#title' => t('Box around'), + '#options' => array( + 'pane' => t('Each pane'), + 'panel' => t('Each region'), + ), + '#default_value' => (isset($style_settings['corner_location'])) ? $style_settings['corner_location'] : 'ul', + '#description' => t('Choose whether to include the box around each pane (piece of content) or region (each column or region)'), + ); + + return $form; +} + +/** + * Generates the dynamic CSS. + * + * @param $display + * A Panels display object. + */ +function panels_rounded_corners_css($display) { + $idstr = empty($display->css_id) ? '.rounded-corner' : "#$display->css_id .rounded-corner"; + $css_id = 'rounded-corner:' . $idstr; + + ctools_include('css'); + $filename = ctools_css_retrieve($css_id); + if (!$filename) { + $filename = ctools_css_store($css_id, _panels_rounded_corners_css($idstr), FALSE); + } + + ctools_css_add_css($filename, 'module', 'all', FALSE); +} + +/** + * Generates the dynamic CSS. + */ +function _panels_rounded_corners_css($idstr) { + $url = panels_get_path('plugins/styles/corners', TRUE); + + $css = <<<EOF + +.t-edge, .b-edge, .l-edge, .r-edge, .wrap-corner { + position: relative; + /* hasLayout -1 ? For IE only */ + zoom: 1; +} +$idstr .t-edge { + background: url('$url/shadow-t.png') repeat-x 0 top; + font-size: 1px; +} +$idstr .b-edge { + background: url('$url/shadow-b.png') repeat-x 0 bottom; + font-size: 1px; +} +$idstr .l-edge { + background: url('$url/shadow-l.png') repeat-y 0 0; +} +$idstr .r-edge { + background: url('$url/shadow-r.png') repeat-y right 0; +} +$idstr .wrap-corner { + background: #fff !important; +} +$idstr .wrap-corner .t-edge, $idstr .wrap-corner .b-edge { + height: 11px; +} +$idstr .wrap-corner .l, $idstr .wrap-corner .r { + position: absolute; + top: 0; + height: 11px; + width: 11px; + background-image: url('$url/corner-bits.png'); +} +$idstr .wrap-corner .l { + left: 0; +} +$idstr .wrap-corner .r { + right: 0; + background-position: -11px 0; +} +$idstr .wrap-corner .b-edge .l { + background-position: 0 -11px; +} +$idstr .wrap-corner .b-edge .r { + background-position: -11px -11px; +} +$idstr .wrap-corner .r-edge { + padding: 5px 24px; +} +$idstr div.admin-links { + margin-top: -14px; + margin-left: -12px; +} + +$idstr .panel-region-separator { + background: url('$url/shadow-b.png') repeat-x 0 center; + font-size: 1px; + height: 30px; +} + +$idstr .rounded-corner { + margin-bottom: 1em; +} + +EOF; + + return $css; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-b.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-b.png new file mode 100644 index 0000000000000000000000000000000000000000..663676edfe683907dc28a6204d9c253fc28aa98d Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-b.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-l.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-l.png new file mode 100644 index 0000000000000000000000000000000000000000..43fd7e71eff8410cb152ab5176c95b4b4a530f22 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-l.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-r.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-r.png new file mode 100644 index 0000000000000000000000000000000000000000..5c972f235c9cbc78ce386fc6220ac076d455562a Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-r.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-t.png b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-t.png new file mode 100644 index 0000000000000000000000000000000000000000..5947889405af1643fbea8d068d3e8c50d5271562 Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/corners/shadow-t.png differ diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/default.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/default.inc new file mode 100644 index 0000000000000000000000000000000000000000..37188ee3e7704dcb7adfe8bccfe153bfe5ac059a --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/default.inc @@ -0,0 +1,38 @@ +<?php + +/** + * @file + * Definition of the 'default' panel style. + */ + +// Plugin definition +$plugin = array( + 'title' => t('No style'), + 'description' => t('The default panel rendering style; displays each pane with a separator.'), + 'render region' => 'panels_default_style_render_region', + 'weight' => -15, +); + +/** + * Render callback. + * + * @ingroup themeable + */ +function theme_panels_default_style_render_region($display, $region_id, $panes, $settings) { + $output = ''; + + $print_separator = FALSE; + foreach ($panes as $pane_id => $pane_output) { + // Add the separator if we've already displayed a pane. + if ($print_separator) { + $output .= '<div class="panel-region-separator"></div>'; + } + + $output .= $pane_output; + // If we displayed a pane, this will become true; if not, it will become + // false. + $print_separator = (bool) $pane_output; + } + + return $output; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/list.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/list.inc new file mode 100644 index 0000000000000000000000000000000000000000..72240fd4de914a537cf5394866e0802fda7ce698 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/list.inc @@ -0,0 +1,54 @@ +<?php + + +/** + * @file + * Definition of the 'list' panel style. + */ + +// Plugin definition +$plugin = array( + 'title' => t('List'), + 'description' => t('Presents the panes in the form of an HTML list.'), + 'render region' => 'panels_list_style_render_region', + 'settings form' => 'panels_list_style_settings_form', +); + +/** + * Render callback. + * + * @ingroup themeable + */ +function theme_panels_list_style_render_region($display, $region_id, $panes, $settings) { + $items = array(); + + foreach ($panes as $pane_id => $item) { + if (isset($item)) { + $items[] = $item; + } + } + + if (empty($settings['list_type'])) { + $settings['list_type'] = 'ul'; + } + + return theme('item_list', $items, NULL, $settings['list_type']); +} + +/** + * Settings form callback. + */ +function panels_list_style_settings_form($style_settings) { + $form['list_type'] = array( + '#type' => 'select', + '#title' => t('List type'), + '#options' => array( + 'ul' => t('Unordered'), + 'ol' => t('Ordered'), + ), + '#default_value' => (isset($style_settings['list_type'])) ? $style_settings['list_type'] : 'ul', + ); + + return $form; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/naked.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/naked.inc new file mode 100644 index 0000000000000000000000000000000000000000..7e0ef592fe6690fc87a4602995798a62aff97a95 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/naked.inc @@ -0,0 +1,24 @@ +<?php + +/** + * @file + * Definition of the 'naked' panel style. + */ + +// Plugin definition +$plugin = array( + 'title' => t('No markup at all'), + 'description' => t('Display the pane with no markup, not even a title.'), + 'render pane' => 'panels_naked_style_render_pane', + 'weight' => -5, +); + +/** + * Render callback. + * + * @ingroup themeable + */ +function theme_panels_naked_style_render_pane($content, $pane, $display) { + return $content->content; +} + diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/stylizer.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/stylizer.inc new file mode 100644 index 0000000000000000000000000000000000000000..32c09898308b0f5332e38495dc087bad873d2fbf --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/styles/stylizer.inc @@ -0,0 +1,349 @@ +<?php + +/** + * @file + * Definition of the 'stylizer' panel style. + */ + +// Plugin definition +$plugin = array( + 'title' => t('Custom style'), + 'weight' => -10, + 'description' => t('Allows choice of a stylizer style'), + + 'render pane' => 'panels_stylizer_stylizer_style_render_pane', + 'pane settings form' => 'panels_stylizer_stylizer_style_settings_form', + + 'render region' => 'panels_stylizer_stylizer_style_render_region', + 'settings form' => 'panels_stylizer_stylizer_style_settings_form', + + // We offer substyles so provide callbacks to do so. + 'get child' => 'panels_stylizer_get_substyle', + 'get children' => 'panels_stylizer_get_substyles', + + // Set up an AJAX callback for the style + 'ajax' => array( + 'custom' => 'panels_stylizer_pane_add_style', + ), +// 'settings validate' => 'panels_stylizer_stylizer_style_settings_validate', +); + +/** + * Merge the main stylizer plugin with a style to create a sub plugin. + * + * This is used for both panels_stylizer_get_substyle and + * panels_stylizer_get_substyles. + */ +function panels_stylizer_merge_plugin($plugin, $style) { + $plugin['name'] = 'stylizer:' . $style->name; + $plugin['title'] = check_plain($style->admin_title); + $plugin['description'] = check_plain($style->admin_description); + $plugin['style'] = $style; + $plugin['weight'] = 0; + + ctools_include('stylizer'); + $base = ctools_get_style_base($style->settings['style_base']); + if ($base['type'] == 'pane') { + unset($plugin['render region']); + } + else { + unset($plugin['render pane']); + } + + unset($plugin['settings form']); + unset($plugin['pane settings form']); + return $plugin; +} + +/** + * Callback to provide a single stored stylizer style. + */ +function panels_stylizer_get_substyle($plugin, $style_name, $substyle_name) { + // Do not worry about caching; Panels is handling that for us. + ctools_include('export'); + $item = ctools_export_crud_load('stylizer', $substyle_name); + if ($item) { + return panels_stylizer_merge_plugin($plugin, $item); + } +} + +/** + * Callback to provide all stored stylizer styles. + */ +function panels_stylizer_get_substyles($plugin, $style_name) { + $styles[$style_name] = $plugin; + ctools_include('export'); + ctools_include('stylizer'); + $items = ctools_export_crud_load_all('stylizer'); + foreach ($items as $name => $item) { + $base = ctools_get_style_base($item->settings['style_base']); + if ($base && $base['module'] == 'panels') { + $styles['stylizer:' . $name] = panels_stylizer_merge_plugin($plugin, $item); + } + } + + return $styles; +} + +function _panels_stylizer_get_style($plugin, $style_settings) { + if (!empty($plugin['style'])) { + return $plugin['style']->settings; + } + + if (empty($style_settings)) { + return array(); + } + + if ($style_settings['style'] == '$') { + return $style_settings['settings']; + } + + ctools_include('export'); + $style = ctools_export_crud_load('stylizer', $style_settings['style']); + if ($style) { + return $style->settings; + } +} + +/** + * Region render theme. + */ +function theme_panels_stylizer_stylizer_style_render_region($display, $owner_id, $panes, $style_settings, $region_id, $plugin) { + $output = ''; + + foreach ($panes as $pane_id => $pane_output) { + $output .= $pane_output; + } + + $settings = _panels_stylizer_get_style($plugin, $style_settings); + + if (!empty($settings)) { + ctools_include('stylizer'); + $plugin = ctools_get_style_base($settings['style_base']); + ctools_stylizer_add_css($plugin, $settings); + + return theme($plugin['theme'], $settings, ctools_stylizer_get_css_class($plugin, $settings), $output); + } + else { + // if the style is gone, just display the output. + return $output; + } +} + +/** + * Pane render theme + */ +function theme_panels_stylizer_stylizer_style_render_pane($content, $pane, $display, $plugin) { + $settings = _panels_stylizer_get_style($plugin, $pane->style['settings']); + + if ($settings) { + ctools_include('stylizer'); + $plugin = ctools_get_style_base($settings['style_base']); + + if (empty($content->css_class)) { + $content->css_class = ctools_stylizer_get_css_class($plugin, $settings); + } + else { + $content->css_class .= ' ' . ctools_stylizer_get_css_class($plugin, $settings); + } + + ctools_stylizer_add_css($plugin, $settings); + + if (isset($plugin['theme'])) { + return theme($plugin['theme'], $settings, $content, $pane, $display); + } + } + + // if the style is gone or has no theme of its own, just display the output. + return theme('panels_pane', $content, $pane, $display); +} + +/** + * Settings form callback. + */ +function panels_stylizer_stylizer_style_settings_form($style_settings, $display, $pid, $type, $form_state) { + // Just redirect this to the custom style settings ajax. + panels_stylizer_pane_add_style($form_state['renderer'], array(), $style_settings, $type, $pid); + ctools_ajax_render($form_state['renderer']->commands); +} + + +/** + * Allow on-the-fly creation of styles in panes. + */ +function panels_stylizer_pane_add_style(&$renderer, $plugin, &$conf, $type, $pid, $step = NULL) { + if (!user_access('administer panels styles')) { + return; + } + + ctools_include('stylizer'); + $js = FALSE; + + $path = $renderer->get_url('style', 'custom', $type, $pid, '%step'); + + $info = array( + 'module' => 'panels', + 'type' => $type, + 'path' => $path, + 'modal' => t('Create custom style'), + 'owner form' => 'panels_stylizer_edit_pane_style_form', + 'owner form validate' => 'panels_stylizer_edit_pane_style_form_validate', + 'owner form submit' => 'panels_stylizer_edit_pane_style_form_submit', + 'owner settings' => array('preconfigured' => FALSE, 'name' => '', 'admin_title' => '', 'admin_description' => ''), + 'cache' => &$renderer->cache, + 'conf' => &$conf, + 'pid' => $pid, + ); + + if (!empty($conf['settings'])) { + $info['settings'] = $conf['settings']; + } + + $output = ctools_stylizer_edit_style($info, TRUE, $step); + if (!empty($info['complete'])) { + if (!empty($info['owner settings']['preconfigured'])) { + ctools_include('export'); + $style = ctools_export_crud_new('stylizer'); + $style->name = $info['settings']['name']; + $style->admin_title = $info['owner settings']['admin_title']; + $style->admin_description = $info['owner settings']['admin_description']; + $style->settings = $info['settings']; + ctools_export_crud_save('stylizer', $style); + $conf['style'] = $info['settings']['name']; + if (isset($conf['settings'])) { + unset($conf['settings']); + } + } + else { + $conf['style'] = '$'; + $conf['settings'] = $info['settings']; + } + + // Be sure to unset the temporary if the style was just changed. + if (isset($renderer->cache->style)) { + unset($renderer->cache->style); + } + // $conf was a reference so it should just modify. + panels_edit_cache_set($renderer->cache); + + $renderer->commands[] = ctools_modal_command_dismiss(); + + if ($type == 'pane') { + $renderer->command_update_pane($pid); + } + else if ($type == 'region') { + $renderer->command_update_region_links($pid); + } + else { + $renderer->command_update_display_links(); + } + } + else { + $renderer->commands = $output; + } +} + + +/** + * The form for determining if a pane should create a local style or a + * preconfigured style. + */ +function panels_stylizer_edit_pane_style_form(&$form, &$form_state) { + if (!user_access('administer panels styles') || !module_exists('stylizer')) { + return; + } + ctools_include('dependent'); + + $settings = $form_state['owner info']['owner settings']; + $form['panels']['admin_title'] = array( + '#type' => 'textfield', + '#title' => t('Administrative title'), + '#description' => t('The name of this style. This will appear in the administrative interface to easily identify it.'), + '#default_value' => $settings['admin_title'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-preconfigured' => array(1)), + ); + + $form['panels']['name'] = array( + '#type' => 'textfield', + '#title' => t('Machine name'), + '#description' => t('The machine readable name of this page. It must be unique, and it must contain only alphanumeric characters and underscores. Once created, you will not be able to change this value!'), + '#default_value' => $settings['name'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-preconfigured' => array(1)), + ); + + $form['panels']['admin_description'] = array( + '#type' => 'textarea', + '#title' => t('Administrative description'), + '#description' => t('A description of what this style is, does or is for, for administrative use.'), + '#default_value' => $settings['admin_description'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-preconfigured' => array(1)), + ); + + // Add the checkbox, set the weight early + $form['panels']['preconfigured'] = array( + '#type' => 'checkbox', + '#title' => t('Make this style available to other regions or panes'), + '#default_value' => $settings['name'], + '#weight' => -1, + ); + +} + +/** + * Validate to see if we need to check the preconfigured values. + */ +function panels_stylizer_edit_pane_style_form_validate(&$form, &$form_state) { + if (!user_access('administer panels styles')) { + return; + } + + // Only validate if preconfigured is checked. + if ($form_state['values']['preconfigured'] && !empty($form_state['clicked_button']['#wizard type'])) { + if (empty($form_state['values']['admin_title'])) { + form_error($form['panels']['admin_title'], t('You must choose an administrative title.')); + } + + // If this is new, make sure the name is unique: + if ($form_state['op'] == 'add') { + if (empty($form_state['values']['name'])) { + form_error($form['panels']['name'], t('You must choose a machine name.')); + } + + ctools_include('export'); + $test = ctools_export_crud_load('stylizer', $form_state['values']['name']); + if ($test) { + form_error($form['panels']['name'], t('That name is used by another style: @page', array('@page' => $test->admin_title))); + } + + // Ensure name fits the rules: + if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) { + form_error($form['panels']['name'], t('Name must be alphanumeric or underscores only.')); + } + } + } +} + +/** + * Store the preconfigured values. + */ +function panels_stylizer_edit_pane_style_form_submit(&$form, &$form_state) { + if (!user_access('administer panels styles')) { + return; + } + + // Only validate if preconfigured is checked. + if ($form_state['values']['preconfigured'] && !empty($form_state['clicked_button']['#wizard type'])) { + $form_state['owner info']['owner settings']['admin_title'] = $form_state['values']['admin_title']; + $form_state['owner info']['owner settings']['admin_description'] = $form_state['values']['admin_description']; + + // Clean up preview files before we set the name + ctools_stylizer_cleanup_style($form_state['plugin'], $form_state['settings']); + + $form_state['settings']['name'] = $form_state['values']['name']; + $form_state['name'] = $form_state['values']['name']; + $form_state['owner info']['owner settings']['preconfigured'] = $form_state['values']['preconfigured']; + } +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/task_handlers/panel_context.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/task_handlers/panel_context.inc new file mode 100644 index 0000000000000000000000000000000000000000..2dccdc7840ace3ae01749cbc89137eee0a9e1380 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/task_handlers/panel_context.inc @@ -0,0 +1,829 @@ +<?php + +/** + * @file + * + * This is the task handler plugin to handle attaching a panel to any + * task that advertises itself as a 'context' type, which all of the + * basic page tasks provided by page_manager.module do by default. + */ + +// Plugin definition +$plugin = array( + // is a 'context' handler type, meaning it supports the API of the + // context handlers provided by ctools context plugins. + 'handler type' => 'context', + 'visible' => TRUE, // may be added up front. + + // Administrative fields. + 'title' => t('Panel'), + 'admin summary' =>'panels_panel_context_admin_summary', + 'admin title' => 'panels_panel_context_title', + 'operations' => array( + 'settings' => array( + 'title' => t('General'), + 'description' => t('Change general settings about this variant.'), + 'form' => 'panels_panel_context_edit_settings', + ), + 'criteria' => array( + 'title' => t('Selection rules'), + 'description' => t('Control the criteria used to decide whether or not this variant is used.'), + 'ajax' => FALSE, + 'form' => array( + 'order' => array( + 'form' => t('Selection rules'), + ), + 'forms' => array( + 'form' => array( + 'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc', + 'form id' => 'ctools_context_handler_edit_criteria', + ), + ), + ), + ), + 'context' => array( + 'title' => t('Contexts'), + 'ajax' => FALSE, + 'description' => t('Add additional context objects to this variant that can be used by the content.'), + 'form' => array( + 'order' => array( + 'form' => t('Context'), + ), + 'forms' => array( + 'form' => array( + 'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc', + 'form id' => 'ctools_context_handler_edit_context', + ), + ), + ), + ), + 'layout' => array( + 'title' => t('Layout'), + 'description' => t('Change the layout of this panel.'), + // No AJAX so we get our CSS loaded. + 'ajax' => FALSE, + 'form' => array( + 'order' => array( + 'choose' => t('Change layout'), + 'move' => t('Move content from old layout'), + ), + 'forms' => array( + 'choose' => array( + 'form id' => 'panels_panel_context_edit_layout', + ), + 'move' => array( + 'include' => array( + drupal_get_path('module', 'panels') . '/includes/display-layout.inc', + ), + 'form id' => 'panels_panel_context_edit_move', + 'submit' => 'panels_change_layout_submit', + ), + ), + ), + ), + 'content' => array( + 'title' => t('Content'), + 'description' => t('Add content items and change their location with a drag and drop interface.'), + 'ajax' => FALSE, + 'form' => array( + 'order' => array( + 'form' => t('Content'), + ), + 'forms' => array( + 'form' => array( + 'include' => array( + drupal_get_path('module', 'panels') . '/includes/display-edit.inc', + ), + 'form id' => 'panels_panel_context_edit_content', + 'no blocks' => TRUE, + ), + ), + ), + ), + 'preview' => array( + 'title' => t('Preview'), + 'description' => t('Get a preview of what this variant will look like.'), + 'form' => 'panels_panel_context_edit_preview', + 'ajax' => FALSE, + 'silent' => TRUE, + 'form info' => array('finish text' => t('Preview')), + 'no update and save' => TRUE, + ), + ), + + 'tab operation' => 'panels_panel_context_tab_operation', + + // Callback to render the data. + 'render' => 'panels_panel_context_render', + + // Various callbacks for operations performed on the handler to ensure + // related data is updated properly. + 'save' => 'panels_panel_context_save', + 'delete' => 'panels_panel_context_delete', + 'export' => 'panels_panel_context_export', + 'clone' => 'panels_panel_context_clone', + + 'add features' => array( + 'criteria' => t('Selection rules'), + 'context' => t('Contexts'), + ), + // Where to go when finished. + 'add finish' => 'content', + + 'required forms' => array( + 'choose' => t('Choose layout'), + 'settings' => t('Panel settings'), + 'content' => t('Panel content'), + ), + + 'edit forms' => array( + 'content' => t('Panel content'), + 'criteria' => t('Selection rules'), + 'settings' => t('General'), + 'context' => t('Contexts'), + 'layout' => t('Change layout'), + 'move' => '', // no title makes it a 'hidden' edit form. + ), + 'forms' => array( + 'settings' => array( + 'form id' => 'panels_panel_context_edit_settings', + ), + 'choose' => array( + 'form id' => 'panels_panel_context_edit_choose', + 'no back validate' => TRUE, + ), + 'layout' => array( + 'no return' => TRUE, + 'form id' => 'panels_panel_context_edit_layout', + ), + 'move' => array( + 'include' => array( + drupal_get_path('module', 'panels') . '/includes/display-layout.inc', + ), + 'form id' => 'panels_panel_context_edit_move', + 'submit' => 'panels_change_layout_submit', + ), + 'content' => array( + 'include' => array( + drupal_get_path('module', 'panels') . '/includes/display-edit.inc', + ), + 'form id' => 'panels_panel_context_edit_content', + 'no blocks' => TRUE, + ), + 'context' => array( + 'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc', + 'form id' => 'ctools_context_handler_edit_context', + ), + 'criteria' => array( + 'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc', + 'form id' => 'ctools_context_handler_edit_criteria', + ), + ), + 'default conf' => array( + 'title' => t('Panel'), + 'no_blocks' => FALSE, + 'pipeline' => 'standard', + 'css_id' => '', + 'css' => '', + 'contexts' => array(), + 'relationships' => array(), + ), +); + +/** + * Provide the operation trail for the 'Edit panel' link. + * + * When editing the panel, go directly to the content tab. + */ +function panels_panel_context_tab_operation($handler, $contexts, $args) { + return array('handlers', $handler->name, 'content'); +} + +/** + * Get the display for a task handler. + * + * There are three methods that the display can be found. + * - In the database. $handler->conf['did'] will be set in this case, + * and $handler->conf['display'] won't be. + * - In $handler->conf['display'], with $handler->conf['did'] empty. This + * will be true for a default/imported task handler as well as a handler + * that has just been created but has not yet been saved. + * - in $handler->conf['display'] with $handler->conf['did' populated. This + * simply means that the display has been modified and is awaiting + * save. The modified one should always be used for editing purposes. + * - If none of the above is true, then a new display needs to be created + * for the handler and pla + */ +function &panels_panel_context_get_display(&$handler) { + if (isset($handler->conf['display'])) { + return $handler->conf['display']; + } + + if (isset($handler->conf['did'])) { + $handler->conf['display'] = panels_load_display($handler->conf['did']); + + // Check for a valid display. If no valid display can be loaded, something + // is wrong and we'll create a new one. + if (!empty($handler->conf['display'])) { + return $handler->conf['display']; + } + } + + $handler->conf['display'] = panels_new_display(); + + return $handler->conf['display']; +} + +/** + * Check selection rules and, if passed, render the contexts. + */ +function panels_panel_context_render($handler, $base_contexts, $args, $test = TRUE) { + // Go through arguments and see if they match. + ctools_include('context'); + ctools_include('context-task-handler'); + ctools_include('plugins', 'panels'); + + // Add my contexts + $contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler); + + // Test. + if ($test && !ctools_context_handler_select($handler, $contexts)) { + return; + } + + if (isset($handler->handler)) { + ctools_context_handler_pre_render($handler, $contexts, $args); + } + + // Load the display + $display = panels_panel_context_get_display($handler); + + $display->context = $contexts; + $display->args = $args; + $display->css_id = $handler->conf['css_id']; + $task_name = page_manager_make_task_name($handler->task, $handler->subtask); + + $display->cache_key = 'panel_context:' . $task_name . ':' . $handler->name; + + // Check to see if there is any CSS. + if (!empty($handler->conf['css'])) { + ctools_include('css'); + $css_id = 'panel_context:' . $handler->name; + $filename = ctools_css_retrieve($css_id); + if (!$filename) { + $filename = ctools_css_store($css_id, $handler->conf['css']); + } + ctools_css_add_css($filename); + } + + // With an argument, this actually sets the display. + panels_get_current_page_display($display); + + // Handle backward compatibility with the IPE checkbox. + if (empty($handler->conf['pipeline'])) { + $handler->conf['pipeline'] = !empty($handler->conf['use_ipe']) ? 'ipe' : 'standard'; + } + + $renderer = panels_get_renderer($handler->conf['pipeline'], $display); + + $info = array( + 'content' => panels_render_display($display, $renderer), + 'no_blocks' => !empty($handler->conf['no_blocks']), + ); + + $info['title'] = $display->get_title(); + + return $info; +} + +/** + * Callback to allow the handler to react to being saved. + * + * When a handler with a display is saved, two things have to happen. + * First, we have to save the display so that it becomes a real display, + * not the fake one we started with. Second, we have to cache + * any CSS that the display is using. This CSS can get re-cached + * later if the file disappears, but it's imperative that we do it here + * to make sure that old, dirty CSS cache gets removed. + */ +function panels_panel_context_save(&$handler, $update) { + // Only save the display if we believe it has been modified. + if (isset($handler->conf['display'])) { + panels_save_display($handler->conf['display']); + $handler->conf['did'] = $handler->conf['display']->did; + unset($handler->conf['display']); + } + + // Delete any previous CSS cache file. + ctools_include('css'); + ctools_css_clear('panel_context:' . $handler->name); + + if (isset($page->conf['temp_layout'])) { + unset($page->conf['temp_layout']); + } +} + +/** + * Special handling for exporting a panel task handler. + * + * When a panel is exported, we need to export the display separately + * rather than just letting its object be unpacked, which does not work + * very well. + */ +function panels_panel_context_export(&$handler, $indent) { + $display = panels_panel_context_get_display($handler); + foreach (array('display', 'did', 'css_cache', 'temp_layout') as $item) { + if (isset($handler->conf[$item])) { + unset($handler->conf[$item]); + } + } + + $output = panels_export_display($display, $indent); + $output .= $indent . '$handler->conf[\'display\'] = $display' . ";\n"; + return $output; +} + +/** + * When a handler is cloned, we have to clone the display. + */ + function panels_panel_context_clone(&$handler) { + $old_display = panels_panel_context_get_display($handler); + $code = panels_export_display($old_display); + eval($code); + foreach (array('display', 'did', 'css_cache', 'temp_layout') as $item) { + if (isset($handler->conf[$item])) { + unset($handler->conf[$item]); + } + } + $display->did = 'new'; + $handler->conf['display'] = $display; +} + +/** + * Callback to delete the display when a handler is deleted. + */ +function panels_panel_context_delete(&$handler) { + if (!empty($handler->conf['did'])) { + panels_delete_display($handler->conf['did']); + } +} + +/** + * Set up a title for the panel based upon the selection rules. + */ +function panels_panel_context_title($handler, $task, $subtask) { + if (isset($handler->conf['title'])) { + return check_plain($handler->conf['title']); + } + else { + return t('Panel'); + } +} + +/** + * Provide a nice little summary of what's in a panel. + * + * The task handler manager provides a summary of a given handler in a + * collapsible div. This callback provides that. For a Panel, we + * provide a summary of the layout type and content on one side, and + * a summary of the contexts in use on the other. + */ +function panels_panel_context_admin_summary($handler, $task, $subtask, $page, $show_title = TRUE) { + $task_name = page_manager_make_task_name($task['name'], $subtask['name']); + $output = ''; + + $display = panels_panel_context_get_display($handler); + + ctools_include('plugins', 'panels'); + ctools_include('context'); + ctools_include('context-task-handler'); + + // Get the operations + $operations = page_manager_get_operations($page); + + // Get operations for just this handler. + $operations = $operations['handlers']['children'][$handler->name]['children']['actions']['children']; + $args = array('handlers', $handler->name, 'actions'); + $rendered_operations = page_manager_render_operations($page, $operations, array(), array('class' => 'actions'), 'actions', $args); + + $layout = panels_get_layout($display->layout); + + $plugin = page_manager_get_task_handler($handler->handler); + + $object = ctools_context_handler_get_task_object($task, $subtask, $handler); + $display->context = ctools_context_load_contexts($object, TRUE); + + $access = ctools_access_group_summary(!empty($handler->conf['access']) ? $handler->conf['access'] : array(), $display->context); + if ($access) { + $access = t('This panel will be selected if @conditions.', array('@conditions' => $access)); + } + else { + $access = t('This panel will always be selected.'); + } + + $rows = array(); + + $type = $handler->type == t('Default') ? t('In code') : $handler->type; + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Storage')), + array('class' => t('page-summary-data'), 'data' => $type), + array('class' => t('page-summary-operation'), 'data' => ''), + ); + + if (!empty($handler->disabled)) { + $link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'enable'))); + $text = t('Disabled'); + } + else { + $link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'disable'))); + $text = t('Enabled'); + } + + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Status')), + array('class' => t('page-summary-data'), 'data' => $text), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + $link = l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'criteria'))); + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Selection rule')), + array('class' => t('page-summary-data'), 'data' => $access), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + $link = l(t('Change layout'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'layout'))); + $link .= '<br />' . l(t('Edit content'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'content'))); + $link .= '<br />' . l(t('Preview'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'preview'))); + $rows[] = array( + array('class' => t('page-summary-label'), 'data' => t('Layout')), + array('class' => t('page-summary-data'), 'data' => check_plain($layout['title'])), + array('class' => t('page-summary-operation'), 'data' => $link), + ); + + $content_link = ' [' . l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'content'))) . ']'; + $context_link = ' [' . l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'context'))) . ']'; + + $info = theme('table', array(), $rows, array('class' => 'page-manager-handler-summary')); + +/* + $content = theme('panels_common_content_list', $display); + if (empty($contents)) { + $contents = t('This panel has no content.'); + } + $contexts = theme('ctools_context_list_no_table', $object); + if (empty($contexts)) { + $contexts = t('This panel has no contexts.'); + } +*/ + + $title = $handler->conf['title']; + if ($title != t('Panel')) { + $title = t('Panel: @title', array('@title' => $title)); + } + + $output .= '<div class="clear-block">'; + if ($show_title) { + $output .= '<div class="handler-title clear-block">'; + $output .= '<div class="actions handler-actions">' . $rendered_operations['actions'] . '</div>'; + $output .= '<span class="title-label">' . $title . '</span>'; + } + + $output .= '</div>'; + $output .= $info; + $output .= '</div>'; +/* + $output .= '<div class="right-container">'; + $output .= '<h3 class="context-title">' . t('Contexts') . $context_link . '</h3>'; + $output .= $contexts; + $output .= '</div>'; + + $output .= '<div class="left-container">'; +// $output .= $icon; + $output .= '<h3 class="handler-title">' . t('Content') . $content_link . '</h3>'; + $output .= $content; + $output .= '</div>'; +*/ + return $output; +} + +// -------------------------------------------------------------------------- +// Forms + +/** + * General notes about forms: The handler is automatically cached by the form + * wizard, so anything we store on $form_state['handler'] anywhere will get + * saved and appear on the next form. The cache is a 'working' cache and + * if the user hits cancel on any page of the multi-page wizard, all + * changes since the last 'update/finish' click will be flushed away. + * + * Many of the Panels forms call through to the real Panels cousins. These + * forms are smart enough to know that they're being wrapped in another + * form and act appropriately. Some of them are so smart that we just let + * their submit and validate handlers do the work rather than writing + * additional ones here. + */ + +/** + * Choose a layout for this panel. + * + * This is only called during 'add', when we know that there isn't a + * previous layout to choose from. a different, only slightly different + * variant is called to change a pre-existing layout. + */ +function panels_panel_context_edit_choose(&$form, &$form_state) { + ctools_include('common', 'panels'); + ctools_include('display-layout', 'panels'); + ctools_include('plugins', 'panels'); + + // @todo -- figure out where/how to deal with this. + $form_state['allowed_layouts'] = 'panels_page'; + + $form_state['display'] = &panels_panel_context_get_display($form_state['handler']); + + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + + // Change the #id of the form so the CSS applies properly. + $form['#id'] = 'panels-choose-layout'; + $form = array_merge($form, panels_choose_layout($form_state)); +} + +/** + * Validate that a layout was chosen. + */ +function panels_panel_context_edit_choose_validate(&$form, &$form_state) { + if (empty($form_state['values']['layout'])) { + form_error($form['layout'], t('You must select a layout.')); + } +} + +/** + * A layout has been selected, set it up. + */ +function panels_panel_context_edit_choose_submit(&$form, &$form_state) { + $form_state['display']->layout = $form_state['values']['layout']; + $form_state['handler']->conf['display'] = $form_state['display']; + if (isset($form_state['page']->display_cache[$form_state['handler_id']])) { + $form_state['page']->display_cache[$form_state['handler_id']]->display = $form_state['display']; + } +} + +/** + * Change the layout for this panel. + * + * This form is only used if a layout already exists and the user wants + * to change to a different one. The submit handler changes the next form + * to the move content form, which is 'hidden' so it won't be accessed + * directly. + */ +function panels_panel_context_edit_layout(&$form, &$form_state) { + ctools_include('common', 'panels'); + ctools_include('display-layout', 'panels'); + ctools_include('plugins', 'panels'); + + // @todo -- figure out where/how to deal with this. + $form_state['allowed_layouts'] = 'panels_page'; + + $form_state['display'] = &panels_panel_context_get_display($form_state['handler']); + + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + + // Change the #id of the form so the CSS applies properly. + $form['#id'] = 'panels-choose-layout'; + $form = array_merge($form, panels_choose_layout($form_state)); +} + +/** + * Validate that a layout was chosen. + */ +function panels_panel_context_edit_layout_validate(&$form, &$form_state) { + $display = &panels_panel_context_get_display($form_state['handler']); + + if (empty($form_state['values']['layout'])) { + form_error($form['layout'], t('You must select a layout.')); + } + if ($form_state['values']['layout'] == $display->layout) { + form_error($form['layout'], t('You must select a different layout if you wish to change layouts.')); + } +} + +/** + * A layout has been selected, set it up. + */ +function panels_panel_context_edit_layout_submit(&$form, &$form_state) { + $display = &panels_panel_context_get_display($form_state['handler']); + + if ($form_state['values']['layout'] != $display->layout) { + $form_state['handler']->conf['temp_layout'] = $form_state['values']['layout']; + } +} + +/** + * When a layout is changed, the user is given the opportunity to move content. + */ +function panels_panel_context_edit_move(&$form, &$form_state) { + $form_state['display'] = &panels_panel_context_get_display($form_state['handler']); + $form_state['layout'] = $form_state['handler']->conf['temp_layout']; + + ctools_include('common', 'panels'); + ctools_include('display-layout', 'panels'); + ctools_include('plugins', 'panels'); + + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + + // Change the #id of the form so the CSS applies properly. + $form = array_merge($form, panels_change_layout($form_state)); + + // Change the 'back' button to just go directly to the previous form +// $task_id = $form_state['task']['name']; +// $handler_id = $form_state['handler']->handler; +// $name = $form_state['handler']->name; + + // This form is outside the normal wizard list, so we need to specify the + // previous/next forms. + $form['buttons']['previous']['#next'] = 'layout'; + $form['buttons']['next']['#next'] = 'content'; + + $form_state['form_info']['return path'] = page_manager_edit_url($form_state['page']->task_name, array('handlers', $form_state['handler_id'], 'content')); +} + +/** + * Present the panels drag & drop editor to edit the display attached + * to the task handler. + */ +function panels_panel_context_edit_content(&$form, &$form_state) { + ctools_include('ajax'); + ctools_include('plugins', 'panels'); + ctools_include('common', 'panels'); + ctools_include('context'); + ctools_include('context-task-handler'); + + $cache = panels_edit_cache_get('panel_context:' . $form_state['task_name'] . ':' . $form_state['handler_id']); + + $form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display); + $form_state['renderer']->cache = &$cache; + + $form_state['display'] = &$cache->display; + $form_state['content_types'] = $cache->content_types; + // Tell the Panels form not to display buttons. + $form_state['no buttons'] = TRUE; + $form_state['display_title'] = !empty($cache->display_title); + $form_state['no preview'] = TRUE; + $form_state['page']->display_cache[$form_state['handler_id']] = $cache; + + $form = array_merge($form, panels_edit_display_form($form_state)); + // Make sure the theme will work since our form id is different. + $form['#theme'] = 'panels_edit_display_form'; + + if (!isset($form_state['type']) || $form_state['type'] != 'add' && !empty($form_state['handler_id']) && !empty($form['buttons'])) { + $form['buttons']['preview'] = $form['buttons']['return']; + $form['buttons']['preview']['#value'] = t('Update and preview'); + } +} + +function panels_panel_context_edit_content_submit(&$form, &$form_state) { + panels_edit_display_form_submit($form, $form_state); + $handler = &$form_state['handler']; + + // update the cached display: + $display = $form_state['page']->display_cache[$form_state['handler_id']]->display; + $handler->conf['display'] = $display; + unset($form_state['page']->display_cache[$form_state['handler_id']]); + + if ($form_state['clicked_button']['#value'] == t('Update and preview')) { + $form_state['new trail'] = array('handlers', $form_state['handler_id'], 'preview'); + } +} + +/** + * General settings for the panel + */ +function panels_panel_context_edit_settings(&$form, &$form_state) { + $conf = $form_state['handler']->conf; + $form['conf']['title'] = array( + '#type' => 'textfield', + '#default_value' => $conf['title'], + '#title' => t('Administrative title'), + '#description' => t('Administrative title of this variant.'), + ); + + $form['conf']['no_blocks'] = array( + '#type' => 'checkbox', + '#default_value' => $conf['no_blocks'], + '#title' => t('Disable Drupal blocks/regions'), + '#description' => t('Check this to have the page disable all regions displayed in the theme. Note that some themes support this setting better than others. If in doubt, try with stock themes to see.'), + ); + + ctools_include('plugins', 'panels'); + $pipelines = panels_get_renderer_pipelines(); + + // Handle backward compatibility with the IPE checkbox. + if (empty($conf['pipeline'])) { + $conf['pipeline'] = !empty($conf['use_ipe']) ? 'ipe' : 'standard'; + } + + // If there are no pipelines, that probably means we're operating in + // legacy mode. + if (empty($pipelines)) { + // We retain the original pipeline so we don't wreck things by installing + // old modules. + $form['conf']['pipeline'] = array( + '#type' => 'value', + '#value' => $conf['pipeline'], + ); + } + else { + $options = array(); + foreach ($pipelines as $name => $pipeline) { + $options[$name] = check_plain($pipeline->admin_title) . '<div class="description">' . check_plain($pipeline->admin_description) . '</div>'; + } + + $form['conf']['pipeline'] = array( + '#type' => 'radios', + '#options' => $options, + '#title' => t('Renderer'), + '#default_value' => $conf['pipeline'], + ); + } + + $form['conf']['css_id'] = array( + '#type' => 'textfield', + '#size' => 35, + '#default_value' => $conf['css_id'], + '#title' => t('CSS ID'), + '#description' => t('The CSS ID to apply to this page'), + ); + + $form['conf']['css'] = array( + '#type' => 'textarea', + '#title' => t('CSS code'), + '#description' => t('Enter well-formed CSS code here; this code will be embedded into the page, and should only be used for minor adjustments; it is usually better to try to put CSS for the page into the theme if possible. This CSS will be filtered for safety so some CSS may not work.'), + '#default_value' => $conf['css'], + ); +} + +/** + * Submit handler for general settings form. + */ +function panels_panel_context_edit_settings_submit(&$form, &$form_state) { + $form_state['handler']->conf['no_blocks'] = $form_state['values']['no_blocks']; + $form_state['handler']->conf['pipeline'] = $form_state['values']['pipeline']; + $form_state['handler']->conf['css_id'] = $form_state['values']['css_id']; + $form_state['handler']->conf['css'] = $form_state['values']['css']; + $form_state['handler']->conf['title'] = $form_state['values']['title']; + + // Unset the old checkbox so we don't store needless data. + if (isset($form_state['handler']->conf['use_ipe'])) { + unset($form_state['handler']->conf['use_ipe']); + } +} + +/** + * Form to show a nice preview. + */ +function panels_panel_context_edit_preview(&$form, &$form_state) { + ctools_include('context'); + ctools_include('context-task-handler'); + + $contexts = ctools_context_handler_get_all_contexts($form_state['task'], $form_state['subtask'], $form_state['handler']); + $form['preview'] = array(); + ctools_context_replace_form($form['preview'], $contexts); + + // automatically preview if there are no argument placeholders. + if (empty($form['preview'])) { + $display = panels_panel_context_get_display($form_state['handler']); + $display->context = $contexts; + $display->skip_cache = TRUE; + $output = panels_render_display($display); + if (isset($form['buttons'])) { + unset($form['buttons']); + } + } + else { + $form['preview']['#tree'] = TRUE; + $form_state['contexts'] = $contexts; + } + + if (!empty($output)) { + $form['output'] = array( + '#value' => $output, + ); + } + + $form_state['do not cache'] = TRUE; +} + +/** + * Display a preview upon submit if arguments were needed. + */ +function panels_panel_context_edit_preview_submit(&$form, &$form_state) { + $display = panels_panel_context_get_display($form_state['handler']); + $display->context = ctools_context_replace_placeholders($form_state['contexts'], $form_state['values']['preview']); + + $form_state['content'] = panels_render_display($display); + $form_state['redirect'] = FALSE; + $form_state['rerender'] = TRUE; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/views/panels.views.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/views/panels.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..a04502d940853ce0133058f1e36075c174f58fb6 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/views/panels.views.inc @@ -0,0 +1,26 @@ +<?php + +/** + * Implementation of hook_views_plugins + */ +function panels_views_plugins() { + $plugins = array( + 'row' => array( + 'panels_fields' => array( + 'title' => t('Panel fields'), + 'help' => t('Displays the fields in a panel rather than using a template.'), + 'handler' => 'panels_views_plugin_row_fields', + 'path' => drupal_get_path('module', 'panels') . '/plugins/views', + 'theme' => 'views_view_fields', + 'theme path' => drupal_get_path('module', 'views') . '/theme', + 'uses fields' => TRUE, + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-row-panels-fields', + 'parent' => 'fields', + ), + ), + ); + + return $plugins; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/plugins/views/panels_views_plugin_row_fields.inc b/drupal/sites/default/boinc/modules/contrib/panels/plugins/views/panels_views_plugin_row_fields.inc new file mode 100644 index 0000000000000000000000000000000000000000..d6082356f6117b9243e5f32f345815c269fa0aae --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/plugins/views/panels_views_plugin_row_fields.inc @@ -0,0 +1,163 @@ +<?php +/** + * @file + * Contains the base row style plugin. + */ + +/** + * The basic 'fields' row plugin + * + * This displays fields one after another, giving options for inline + * or not. + * + * @ingroup views_row_plugins + */ +class panels_views_plugin_row_fields extends views_plugin_row_fields { + function option_definition() { + $options = parent::option_definition(); + + $options['layout'] = array('default' => 'twocol'); + $options['regions'] = array('default' => array()); + + return $options; + } + + /** + * Provide a form for setting options. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + ctools_include('plugins', 'panels'); + $layouts = panels_get_layouts(); + $options = array(); + foreach ($layouts as $name => $layout) { + if (empty($layout['builder'])) { + $options[$name] = $layout['title']; + } + if ($name == $this->options['layout']) { + $current_layout = $layout; + } + } + + $form['layout'] = array( + '#prefix' => '<div class="container-inline">', + '#type' => 'select', + '#options' => $options, + '#title' => t('Panel layout'), + '#default_value' => $this->options['layout'], + ); + + $form['change'] = array( + '#type' => 'submit', + '#value' => t('Change'), + '#submit' => array('panels_change_layout_button'), + '#suffix' => '</div>', + ); + + if (!empty($current_layout)) { + $fields = $this->display->handler->get_field_labels(); + $regions = panels_get_regions($current_layout, panels_new_display()); + foreach ($fields as $id => $title) { + $form['regions'][$id] = array( + '#type' => 'select', + '#title' => $title, + '#options' => $regions, + ); + if (!empty($this->options['regions'][$id]) && !empty($regions[$this->options['regions'][$id]])) { + $form['regions'][$id]['#default_value'] = $this->options['regions'][$id]; + } + } + } + } + + /** + * Perform any necessary changes to the form values prior to storage. + * There is no need for this function to actually store the data. + */ + function options_submit($form, &$form_state) { + $form_state['values']['row_options']['inline'] = array_filter($form_state['values']['row_options']['inline']); + } + + /** + * Render a row object. This usually passes through to a theme template + * of some form, but not always. + */ + function render($row) { + ctools_include('plugins', 'panels'); + $layout = panels_get_layout($this->options['layout']); + if (!$layout) { + // Fall back to normal behavior if the layout is somehow invalid. This + // can happen if the layout was removed, for example. + return theme($this->theme_functions(), $this->view, $this->options, $row, $this->field_alias); + } + + // Store a backup copy of the array because we're going to be screwing + // with this a lot. + $fields = $this->view->field; + unset($this->view->field); + + $meta = 'standard'; + // This row style gets run many times; only run this code once. + if (empty($this->region_fields)) { + $this->region_fields = array(); + $regions = panels_get_regions($layout, panels_new_display()); + + // Ensure each region has an empty array. + foreach ($regions as $region_id => $name) { + if (empty($default_region)) { + $default_region = $region_id; + } + + $this->region_fields[$region_id] = array(); + } + + + // Go through all our fields and place them in regions according to the + // settings. + foreach ($fields as $id => $field) { + $region_id = ''; // ensure we don't accidentlly use the last field's region. + if (!empty($this->options['regions'][$id]) && !empty($regions[$this->options['regions'][$id]])) { + $region_id = $this->options['regions'][$id]; + } + else { + // Fallback to putting unknown fields into the first region. + $region_id = $default_region; + } + + // Ensure this works in PHP4 by keeping the reference. + $this->region_fields[$region_id][$id] = &$fields[$id]; + } + + // We don't need to set 'inline' for every record, so we do it inside + // this loop. We do need to set inline if we are in the live preview + // so that the CSS will get transmitted via javascript: + $meta = !empty($this->view->live_preview) ? 'inline' : 'standard'; + } + + // Now that we have distributed our fields, go through the regions and + // render them into the content array. + foreach ($this->region_fields as $region_id => $fields) { + $this->view->field = $fields; + $content[$region_id] = theme($this->theme_functions(), $this->view, $this->options, $row, $this->field_alias); + } + + // Restore our $fields array. + $view->field = $fields; + + // Now that we have a rendered content array, render it. + return panels_print_layout($layout, $content, $meta); + } +} + +/** + * Override handler for views_ui_edit_display_form + */ +function panels_change_layout_button($form, &$form_state) { + $display = &$form_state['view']->display[$form_state['display_id']]; + $display->handler->options_submit($form, $form_state); + + views_ui_cache_set($form_state['view']); + $form_state['rerender'] = TRUE; + $form_state['rebuild'] = TRUE; +} diff --git a/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard-block.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard-block.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..c2a665e80d2eb996f433f59cc058ade057bc3ca1 --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard-block.tpl.php @@ -0,0 +1,13 @@ +<?php +?> +<div class="dashboard-block"> + <h3 class="dashboard-title"><?php print $block['title']; ?></h3> + <div class="dashboard-content <?php print $block['class']; ?>"> + <?php print $block['content']; ?> + <?php if (!empty($block['link'])): ?> + <div class="links"> + <?php print $block['link']; ?> + </div> + <?php endif; ?> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard-link.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard-link.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..681a7237fcc60119f2cfd22ca67d794d487cfe0d --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard-link.tpl.php @@ -0,0 +1,12 @@ +<?php +?> +<div class="dashboard-entry clear-block"> + <div class="dashboard-text"> + <div class="dashboard-link"> + <?php print $link['title']; ?> + </div> + <div class="description"> + <?php print $link['description']; ?> + </div> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..75c9e4c6e9b7b764b351b785c3590f7fb19665ae --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-dashboard.tpl.php @@ -0,0 +1,11 @@ +<?php +?> +<div class="panels-dashboard"> + <div class="dashboard-left clear-block"> + <?php print $left; ?> + </div> + + <div class="dashboard-right clear-block"> + <?php print $right; ?> + </div> +</div> diff --git a/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-pane.tpl.php b/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-pane.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..c7ea90f045de026a6a7b6ca2116520a73c1e822e --- /dev/null +++ b/drupal/sites/default/boinc/modules/contrib/panels/templates/panels-pane.tpl.php @@ -0,0 +1,52 @@ +<?php +/** + * @file panels-pane.tpl.php + * Main panel pane template + * + * Variables available: + * - $pane->type: the content type inside this pane + * - $pane->subtype: The subtype, if applicable. If a view it will be the + * view name; if a node it will be the nid, etc. + * - $title: The title of the content + * - $content: The actual content + * - $links: Any links associated with the content + * - $more: An optional 'more' link (destination only) + * - $admin_links: Administrative links associated with the content + * - $feeds: Any feed icons or associated with the content + * - $display: The complete panels display object containing all kinds of + * data including the contexts and all of the other panes being displayed. + */ +?> +<div class="<?php print $classes; ?>" <?php print $id; ?>> + <?php if ($admin_links): ?> + <div class="admin-links panel-hide"> + <?php print $admin_links; ?> + </div> + <?php endif; ?> + + <?php if ($title): ?> + <h2 class="pane-title"><?php print $title; ?></h2> + <?php endif; ?> + + <?php if ($feeds): ?> + <div class="feed"> + <?php print $feeds; ?> + </div> + <?php endif; ?> + + <div class="pane-content"> + <?php print $content; ?> + </div> + + <?php if ($links): ?> + <div class="links"> + <?php print $links; ?> + </div> + <?php endif; ?> + + <?php if ($more): ?> + <div class="more-link"> + <?php print $more; ?> + </div> + <?php endif; ?> +</div>